uva1599 理想路径
对于一个n个房间m条路径的迷宫(Labyrinth)(2<=n<=100000, 1<=m<=200000),每条路径上都涂有颜色,颜色取值范围为1<=c<=10^9。求从节点1到节点n的一条路径,使得经过的边尽量少,在这样的前提下,如果有多条路径边数均为最小,则颜色的字典序最小的路径获胜。一条路径可能连接两个相同的房间,一对房间之间可能有多条路径。输入保证可以从节点1到达节点n。
对于这个问题,首先我们需要保证最短路,在这个前提下,我们要保证颜色的字典序尽可能小,解决这个问题,我们可以先从终点开始做一次bfs,统计出每个点到终点需要的最短步数。之后从起点出发,每一步在距离相等的点中选择颜色最小的点。只需要两次bfs就解决了这个问题。
#include<bits/stdc++.h> using namespace std; struct Edge { int next; int color; }edge[200000]; int d[100000]; //该点离终点最短的距离 int ans[100000]; //记录路径上的点 int n,m; queue<int> Q; vector<Edge> A[100000]; void bfs1() { while(!Q.empty()) { int x=Q.front();//点 Q.pop(); int t=Q.front();//距离 Q.pop(); for(int i=0;i<A[x].size();i++) { int nx=A[x][i].next; if(d[nx]!=-1)continue; d[nx]=t+1; Q.push(nx); Q.push(d[nx]); } } } void bfs2() { while(!Q.empty()) { int x=Q.front(); Q.pop(); if(x==n) return; int mincol=12111414; for(int i=0;i<A[x].size();i++) { int x1=A[x][i].next; int c=A[x][i].color; if(d[x1]==d[x]-1&&c<mincol)//注意d[x]中记录的数据是倒序的 mincol=c; } if(mincol<ans[d[x]]||ans[d[x]]==-1) ans[d[x]]=mincol; for(int i=0;i<A[x].size();i++) { int x1=A[x][i].next; int c1=A[x][i].color; if(d[x]-1==d[x1]&&c1==mincol) Q.push(x1); } } } int main() { while(cin>>n>>m) {memset(d,-1,sizeof(d)); for(int i=1;i<=m;i++) {int a,b,c; cin>>a>>b>>c; Edge tmp; tmp.next=b; tmp.color=c; A[a].push_back(tmp); tmp.next=a; A[b].push_back(tmp); } d[n]=0; Q.push(n); Q.push(d[n]); bfs1(); Q.push(1); memset(ans,-1,sizeof(ans)); bfs2(); cout<<d[1]<<endl; for(int i=d[1];i>d[n];i--) { cout<<ans[i]<<" "; } cout<<endl; } return 0; }

浙公网安备 33010602011771号