Codeforces-1473 E. Minimum Path(分層圖(多維)最短路)
阿新 • • 發佈:2021-01-17
技術標籤:# codeforces# 最短路
題意:
一條路徑的花費為
求1點到其他所有點路徑的最小花費。
思路:
每個路徑可以分出兩種操作:減掉一條邊,加上一條邊。
那麼定義
d
i
s
[
i
]
[
0
/
1
]
[
0
/
1
]
dis[i][0/1][0/1]
dis[i][0/1][0/1]代表1到
i
i
i路徑的最小花費,以及包括第一次操作的使用情況,第二次操作的使用情況。
然後就
d
i
j
dij
dij轉移就好了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
const int INF = 0x3f3f3f3f;
ll dis[maxn][2][2];
bool vis[maxn][2][2];
int head[maxn],nex[maxn * 2],to[maxn * 2],val[maxn * 2],tot;
struct Node {
int x,y,z;
ll v;
bool operator < (const Node &rhs) const {
return v > rhs.v;
}
};
void add(int x,int y,int z) {
to[++tot] = y;
nex[tot] = head[x];
val[tot] = z;
head[x] = tot;
}
void dijkstra() {
priority_queue<Node>q;
q.push({1,0,0,0});
memset(dis,0x3f,sizeof(dis));
dis[1][0][0] = 0;
while(!q.empty()) {
Node now = q.top();q.pop();
int x = now.x,y = now.y,z = now.z;
if(vis[x][y][z]) continue;
vis[x][y][z] = 1;
for(int i = head[x];i;i = nex[i]) {
int v = to[i],w = val[i];
if(dis[v][y][z] > dis[x][y][z] + w) {
dis[v][y][z] = dis[x][y][z] + w;
q.push({v,y,z,dis[v][y][z]});
}
if(!y) {
if(dis[v][y ^ 1][z] > dis[x][y][z]) {
dis[v][y ^ 1][z] = dis[x][y][z];
q.push({v,y ^ 1,z,dis[v][y ^ 1][z]});
}
}
if(!z) {
if(dis[v][y][z ^ 1] > dis[x][y][z] + w * 2) {
dis[v][y][z ^ 1] = dis[x][y][z] + w * 2;
q.push({v,y,z ^ 1,dis[v][y][z ^ 1]});
}
}
if(!y && !z) {
if(dis[v][y ^ 1][z ^ 1] > dis[x][y][z] + w) {
dis[v][y ^ 1][z ^ 1] = dis[x][y][z] + w;
q.push({v,y ^ 1,z ^ 1,dis[v][y ^ 1][z ^ 1]});
}
}
}
}
}
int main() {
int n,m;scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i++) {
int x,y,z;scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
dijkstra();
for(int i = 2;i <= n;i++) {
printf("%lld ",dis[i][1][1]);
}
return 0;
}