UVa1599/poj 3967 Ideal Path

来源:互联网 发布:图标php导航源码 编辑:程序博客网 时间:2024/04/30 20:42

        题意:一个连通的带权(权表示的不是距离,相邻点距离为1)无向图,有n个点,m条边,从点1走到点n,求最短路径,如果有多条路径最短,输出权的字典序最小的路径。

        思路:先倒着BFS一次,记录每个点到终点的距离,然后正向BFS,每一步走到的点,距离应该比上一步少1。枚举满足上述条件的点,找出全最小的那个(些)点进行扩展。

        这题我WA,RE,TLE了好几页,血的教训啊。。。因为题目数据量大,我没用STL,手写的队列和链表,需要为队列开空间。然后我在第二次BFS时没有检查入队的元素是否已在队列中,爆队了。。可是poj返回的是WA,害我一直在找其他的原因,然后我用其他语言提交,发现变成了RE,把队列开大变成TLE。。。最后才发现问题的原因。。


#include <iostream>             #include <stdio.h>             #include <cmath>             #include <algorithm>             #include <iomanip>             #include <cstdlib>             #include <string>             #include <string.h>             #include <vector>             #include <queue>             #include <stack>             #include <map>           #include <set>           #include <ctype.h>             #define INF 1<<30         #define ll long long         #define max3(a,b,c) max(a,max(b,c))         #define MAXN 1000        using namespace std;        struct edge{        int v;        int c;    };      edge eg[410000];int head[410000];  int next[410000];int level[110000];int tmp[410000];bool vis[110000];    int minc[110000]; int Q[410000];int main(){    int n,m;        while(~scanf("%d%d",&n,&m)){                int front=0;          int rear=0;          memset(level,0,sizeof(level));            memset(head,-1,sizeof(head));          memset(next,-1,sizeof(next));          memset(vis,0,sizeof(vis));            for(int i=0;i<=n;i++)minc[i]=INF;                    for(int i=1;i<=m;i++){                int u,v,c;                scanf("%d%d%d",&u,&v,&c);                int h;                            eg[i*2-1].v=v; eg[i*2-1].c=c;               next[i*2-1]=head[u];              head[u]=i*2-1;                                          eg[i*2].v=u; eg[i*2].c=c;                next[i*2]=head[v];              head[v]=i*2;                        }             Q[rear++]=n;          level[n]=1;            vis[n]=1;          while(front!=rear){                  int cur=Q[front]; front++;                int t=head[cur];              while(t!=-1){                    int v=eg[t].v;                    if( !vis[v]){                        level[v]=level[cur]+1;                         Q[rear++]=v;                      vis[v]=1;                    }                    t=next[t];              }            }        memset(vis,0,sizeof(vis));         int test=rear;          front=rear=0;          Q[rear++]=1;          int k=level[1];          for(int i=k;i>1;i--){              int end=0;              while(front!=rear){                    int cur=Q[front]; front++;                  tmp[end++]=cur;              }              for(int j=0;j<end;j++){                  int cur=tmp[j];                  int t=head[cur];                   while(t!=-1){                      int v=eg[t].v;                      if( !vis[v]&&level[v]==i-1 && eg[t].c<minc[i-1]  ){                            minc[i-1]= eg[t].c;                        }                        t=next[t];                  }              }                            for(int j=0;j<end;j++){                  int cur=tmp[j];                  int t=head[cur];                   while(t!=-1){                      int v=eg[t].v;                      if( !vis[v]&&level[v]==i-1 && eg[t].c==minc[i-1]  ){                            vis[v]=1;                        Q[rear++]=v;                      }                       t=next[t];                  }              }          }                    printf("%d\n",level[1]-1);            for(int i=k-1;i>=1;i--){              printf("%d",minc[i]);              if(i!=1)printf(" ");          }          printf("\n");      }        return 0;    }    


0 0
原创粉丝点击