Educational Codeforces Round 102 (Rated for Div. 2) E. Minimum Path

最短路变形:用一条最小边替换一条最大边意义下的最短路

分层图,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('
')
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;
}

原文地址:https://www.cnblogs.com/ghostcai/p/14290887.html