zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    实现CA和证书申请
    1.ssh端口
    1.对称加密6和7的操作
    关于网页访问并发量,统计前十,防火墙
    双指针法
    并查集
    c++常用函数
    vector常用方法
    贪心算法
    字符串类问题
  • 原文地址:https://www.cnblogs.com/ghostcai/p/14290887.html
Copyright © 2011-2022 走看看