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点。

  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 }
View Code

 

posted @ 2013-09-13 21:29  ihge2k  阅读(252)  评论(0编辑  收藏  举报