题意:
给出n和m,n代表有n个城市。接下来m行,分别给出a,b,c。代表a与b之间有一条颜色为c的道路。求最少走几条道路才能从1走到n。输出要走的道路数和颜色.保证颜色的字典序最小。
分析:
bfs,先倒搜一次,求出每个点到终点的距离d[i]。然后从起点走,每次走到新点保证d-1且颜色最小。
代码:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn = 100010; vector<int>g[maxn]; vector<int>c[maxn]; int step[maxn]; int ans[maxn<<1]; int vis[maxn]; int flag; void bfs1(int n) { queue<int>q; step[n]=0; q.push(n); while(!q.empty()) { int u=q.front(); q.pop(); int sz=g[u].size(); for(int v=0;v<sz;v++) { int vv=g[u][v]; if(vv==1) { step[1]=step[u]+1; return; } if(step[vv]==-1) { step[vv]=step[u]+1; q.push(vv); } } } return; } void bfs2() { memset(vis,0,sizeof(vis)); queue<int>q; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); if(step[u]==0) return; int sz=g[u].size(); int ff=0; int min_=-1; for(int i=0;i<sz;i++) { int vv=g[u][i]; if(step[vv]==step[u]-1) { if(min_==-1) min_=c[u][i]; else min_=min(min_,c[u][i]); } } int tt=step[1]-step[u]; if(ans[tt]==0) ans[tt]=min_; else ans[tt]=min(min_,ans[tt]); for(int v=0;v<sz;v++) { int vv=g[u][v]; if(vis[vv]==0&&step[vv]==step[u]-1&&c[u][v]==min_) { q.push(vv); vis[vv]=1; } } } return; } int main() { int n,m; int a,b,c1; while(scanf("%d%d",&n,&m)!=EOF) { int i,j; for(i=0;i<maxn;i++) g[i].clear(); for(i=0;i<maxn;i++) c[i].clear(); for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c1); if(a==b) continue; g[a].push_back(b); g[b].push_back(a); c[a].push_back(c1); c[b].push_back(c1); } memset(step,-1,sizeof(step)); memset(ans,0,sizeof(ans)); step[n]=-1; bfs1(n); //cout<<step[1]<<endl; bfs2(); printf("%d\n",step[1]); for(i=0;i<step[1];i++) { if(i) printf(" "); printf("%d",ans[i]); } printf("\n"); } }
时间: 2024-10-21 17:12:25