hdu 3760(2次bfs求最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3760
思路:首先是建反图,从点n开始做spfa求出n到各点的最短路,然后从1点开始搜最小序列,对于边(u,v),若dist[u]==dist[v]+1,则要将当前的序号加入当前队列中,然后就是对于那些序号相同点的都要加入当前队列,还要判一下重。至于为什么要建反图从n点开始求最短路,因为在搜最小序列的时候要保证一定能搜到n点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define MAXN 1000000 9 #define inf 1<<30 10 11 struct Edge{ 12 int v,w,color,next; 13 }edge[MAXN]; 14 15 int n,m,NE; 16 int head[MAXN]; 17 18 void Insert(int u,int v,int w,int color) 19 { 20 edge[NE].v=v; 21 edge[NE].w=w; 22 edge[NE].color=color; 23 edge[NE].next=head[u]; 24 head[u]=NE++; 25 } 26 27 bool mark[MAXN]; 28 int dist[MAXN]; 29 void spfa() 30 { 31 memset(mark,false,sizeof(mark)); 32 fill(dist,dist+MAXN,inf); 33 dist[n]=0; 34 queue<int>que; 35 que.push(n); 36 while(!que.empty()){ 37 int u=que.front(); 38 que.pop(); 39 mark[u]=false; 40 for(int i=head[u];i!=-1;i=edge[i].next){ 41 int v=edge[i].v,w=edge[i].w; 42 if(dist[u]+w<dist[v]){ 43 dist[v]=dist[u]+w; 44 if(!mark[v]){ 45 mark[v]=true; 46 que.push(v); 47 } 48 } 49 } 50 } 51 } 52 53 int vv[MAXN]; 54 void BFS() 55 { 56 memset(mark,false,sizeof(mark)); 57 queue<int>que; 58 que.push(1); 59 int flag=1; 60 while(!que.empty()){ 61 int num=0,ans=inf; 62 int u=que.front(); 63 if(u==n)break; 64 int size=que.size(); 65 while(size--){ 66 u=que.front(); 67 que.pop(); 68 for(int i=head[u];i!=-1;i=edge[i].next){ 69 int v=edge[i].v,w=edge[i].w,color=edge[i].color; 70 if(dist[u]==dist[v]+w){ 71 if(color<ans){ 72 ans=color; 73 num=0; 74 vv[num++]=v; 75 }else if(color==ans){ 76 vv[num++]=v; 77 } 78 } 79 } 80 } 81 if(flag){ 82 printf("%d",ans); 83 flag=0; 84 }else 85 printf(" %d",ans); 86 for(int i=0;i<num;i++){ 87 if(mark[vv[i]])continue; 88 mark[vv[i]]=true; 89 que.push(vv[i]); 90 } 91 } 92 puts(""); 93 } 94 95 int main() 96 { 97 int _case,u,v,color; 98 scanf("%d",&_case); 99 while(_case--){ 100 scanf("%d%d",&n,&m); 101 NE=0; 102 memset(head,-1,sizeof(head)); 103 while(m--){ 104 scanf("%d%d%d",&u,&v,&color); 105 Insert(u,v,1,color); 106 Insert(v,u,1,color); 107 } 108 spfa(); 109 printf("%d\n",dist[1]); 110 BFS(); 111 } 112 return 0; 113 }