• UVA


    传送门

    题意

    求带边权无向图从起点到终点的边权字典序最小的最短路路径

    解法

    两遍 BFS
    第一遍逆向,给图分层
    第二遍求路径,每层的点都只能沿最小的边权走向下一层的点。

    代码

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    typedef long long LL;
    const int inf=0x3f3f3f3f;
    const LL INF=0x3f3f3f3f3f3f3f3f;
    const int MAXN=1e5+10;
    
    int n,m;
    int head[MAXN],nxt[MAXN*4],to[MAXN*4],c[MAXN*4],tot=1;
    int dis[MAXN],from[MAXN],path[MAXN];
    bool vis[MAXN];
    queue<int> que;
    queue<vector<int> > q2;
    
    void add(int u,int v,int w){
    	to[++tot]=v;c[tot]=w;nxt[tot]=head[u];head[u]=tot;
    	to[++tot]=u;c[tot]=w;nxt[tot]=head[v];head[v]=tot;
    }
    
    void bfs1(){
    	while(!que.empty()) que.pop();
    	memset(dis,0x3f,sizeof(dis));
    	dis[n]=0;que.push(n);
    	while(!que.empty()){
    		int u=que.front();que.pop();
    		for(int i=head[u];i;i=nxt[i])
    			if(dis[to[i]]>dis[u]+1){
    				dis[to[i]]=dis[u]+1;
    				que.push(to[i]);
    			}
    	}
    }
    void bfs2(){
    	memset(path,0x3f,sizeof(path));
    	memset(vis,0,sizeof(vis));
    	vector<int> vec;
    	vec.push_back(1);
    	q2.push(vec);
    	while(!q2.empty()){
    		vector<int> uv=q2.front();q2.pop();
    		vec.clear();
    		int color=inf;
    		for(int i=0;i<uv.size();i++){
    			int u=uv[i];
    			for(int j=head[u];j;j=nxt[j])
    				if(dis[to[j]]==dis[u]-1)
    					color=min(color,c[j]);
    		}
    		for(int i=0;i<uv.size();i++){
    			int u=uv[i];
    			for(int j=head[u];j;j=nxt[j])
    				if(dis[to[j]]==dis[u]-1&&c[j]==color&&!vis[to[j]]){
    					from[to[j]]=u;
    					path[to[j]]=color;
    					vec.push_back(to[j]);
    					vis[to[j]]=1;
    				}
    		}
    		if(!vec.empty()) q2.push(vec);
    	}
    }
    
    void print(int now){
    	if(now==1) return;
    	print(from[now]);
    	printf("%d",path[now]);
    	if(now!=n) printf(" ");
    }
    
    void solve(){
    	tot=1;
    	memset(head,0,sizeof(head));
    	for(int i=1,u,v,w;i<=m;i++){
    		scanf("%d%d%d",&u,&v,&w);
    		add(u,v,w);
    	}
    	bfs1();
    	bfs2();
    	printf("%d
    ",dis[1]);
    	print(n);
    	printf("
    ");
    }
    
    int main(){
    	while(~scanf("%d%d",&n,&m))
    		solve();
    	return 0;
    }
    
  • 相关阅读:
    WCF之ABC
    一次性为自定义实体类的数据填充
    在HttpHandlers中使用Session
    ASP.NET 2.0防止同一用户同时登陆
    Winson.Framework 1.5发布!
    SqlPager分页控件的使用!
    ExtJS 学习心得(一)
    [原创]Discuz!NT1.1高亮代码插件1.5稳定版!
    Winson.Framework 1.0发布!
    一个不错的WEB打印解决方案!
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11932935.html
Copyright © 2020-2023  润新知