标签:getchar top cat cpp c++ tchar 表示 end pre
最短路变形:用一条最小边替换一条最大边意义下的最短路
分层图,dis[i][0/1][0/1]表示点i,是否经过最小边,是否经过最大边
最小边两倍贡献,最大边0贡献
/*
* Author : GhostCai
* Expecto Patronum
*/
#include<bits/stdc++.h>
#define int long long
using namespace std;
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
cerr << " " << H;
debug_out(T...);
}
#define debug(...) cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define eep(x,y) for(int x=head[y];x;x=e[x].next)
inline int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c==‘-‘?-1:1;
while(isdigit(c))ret=ret*10+c-‘0‘,c=getchar();
return ret*f;
}
#define pc putchar
#define space() pc(‘ ‘)
#define nextline() pc(‘\n‘)
void pot(int x){if(!x)return;pot(x/10);pc(‘0‘+x%10);}
void out(int x){if(!x)pc(‘0‘);if(x<0)pc(‘-‘),x=-x;pot(x);}
const int MAXN = 200005;
struct Edge{
int next,to,w;
}e[MAXN*8];
int ecnt,head[MAXN*4];
inline void add(int x,int y,int w){
e[++ecnt]={head[x],y,w};
head[x]=ecnt;
}
struct Node{
int id,bmn,bmx,w;
bool operator < (const Node &rhs) const{
return w>rhs.w;
}
};
priority_queue<Node> Q;
int dis[MAXN][2][2];
int vis[MAXN][2][2];
int n,m;
void dij(){
rep(i,1,n)
dis[i][0][0]=dis[i][0][1]=dis[i][1][0]=dis[i][1][1]=1ll<<60;
dis[1][0][0]=0;
Q.push({1,0,0,0});
while(!Q.empty()){
Node top=Q.top();Q.pop();
int cur=top.id;
int bmn=top.bmn,bmx=top.bmx;
if(vis[cur][bmn][bmx]) continue;
if(top.w!=dis[cur][bmn][bmx]) continue;
vis[cur][bmn][bmx]=1;
eep(i,cur){
int v=e[i].to,w=e[i].w;
if(dis[v][bmn][bmx]>dis[cur][bmn][bmx]+w){
dis[v][bmn][bmx]=dis[cur][bmn][bmx]+w;
Q.push({v,bmn,bmx,dis[v][bmn][bmx]});
}
if(bmn==0&&dis[v][1][bmx]>dis[cur][bmn][bmx]+w*2){
dis[v][1][bmx]=dis[cur][bmn][bmx]+w*2;
Q.push({v,1,bmx,dis[v][1][bmx]});
}
if(bmx==0&&dis[v][bmn][1]>dis[cur][bmn][bmx]){
dis[v][bmn][1]=dis[cur][bmn][bmx];
Q.push({v,bmn,1,dis[v][bmn][1]});
}
}
}
}
void solve(){
n=rd();m=rd();
rep(i,1,m){
int x,y,w;
x=rd();y=rd();w=rd();
add(x,y,w);
add(y,x,w);
}
dij();
rep(i,2,n) {out(min(dis[i][1][1],dis[i][0][0]));space();}
}
signed main(){
int T=1;
while(T--){
solve();
}
return 0;
}
Educational Codeforces Round 102 (Rated for Div. 2) E. Minimum Path
标签:getchar top cat cpp c++ tchar 表示 end pre
原文地址:https://www.cnblogs.com/ghostcai/p/14290887.html