uva 1599 ideal path(好题)——yhx

来源:互联网 发布:网络整改方案 编辑:程序博客网 时间:2024/04/25 11:57

 1 #include<cstdio> 2 #include<queue> 3 #include<stack> 4 #include<cstring>  5 using namespace std; 6 queue<int> q1,q2; 7 stack<int> s; 8 int first[100010],next[400010],to[400010],dis[100010]; 9 long long color[400010],ans[100010],pre_color[100010];10 bool vis[100010];11 int main()12 {13     int i,j,k,m,n,p,x,y;14     long long min,z;15     while(scanf("%d%d",&n,&m)==2)16     {17         memset(first,0,sizeof(first));18         memset(next,0,sizeof(next));19         memset(to,0,sizeof(to));20         memset(color,0,sizeof(color));21         memset(dis,0,sizeof(dis));22         memset(ans,0,sizeof(ans));23         memset(vis,0,sizeof(vis));24         for (i=1;i<=m;i++)25         {26             scanf("%d%d%lld",&x,&y,&z);27             next[i]=first[x];28             first[x]=i;29             to[i]=y;30             color[i]=z;31             next[i+m]=first[y];32             first[y]=i+m;33             to[i+m]=x;34             color[i+m]=z;35         }36         memset(dis,0x7f,sizeof(dis));37         dis[n]=0;38         while (!q1.empty()) q1.pop();39         q1.push(n);40         while (!q1.empty())41         {42             x=q1.front();43             q1.pop();44             for (i=first[x];i;i=next[i])45               if (dis[x]+1<dis[to[i]])46               {47                   dis[to[i]]=dis[x]+1;48                   q1.push(to[i]);49               }50         }51         memset(ans,0x7f,sizeof(ans));52         ans[0]=0;53         while (!q2.empty()) q2.pop();54         q2.push(1);55         while (!q2.empty())56         {57             x=q2.front();58             q2.pop();59             if (pre_color[x]!=ans[dis[1]-dis[x]]) continue;60             if (x==n) break;61             if (vis[x]) continue;62             vis[x]=1;63             for (i=first[x];i;i=next[i])64               if (dis[to[i]]==dis[x]-1&&color[i]<ans[dis[1]-dis[to[i]]])65                 ans[dis[1]-dis[to[i]]]=color[i];66             for (i=first[x];i;i=next[i])67               if (dis[to[i]]==dis[x]-1&&color[i]==ans[dis[1]-dis[to[i]]])68               {69                   q2.push(to[i]);70                   pre_color[to[i]]=ans[dis[1]-dis[to[i]]];71               }72         }73         printf("%d\n",dis[1]);74         printf("%d",ans[1]);75         for (i=2;i<=dis[1];i++)76           printf(" %d",ans[i]);77         printf("\n");78     }79 }

所求路线有两个要求,一是距离最短,二是在一的前提下字母序最小。因此进行BFS时,需要同时顾及两个因素。

保证距离最短时,可以先从终点出发求一遍最短路,这样每次BFS时只要保证下一步的点的最短路比当前点小1,最后求出来的就一定是最短路。

处理字典序时,采用贪心策略,即从头开始每一步都要最小。对一个点操作时比较路线与已知答案,如果劣于已知答案直接舍去。

注意判重,不重复搜索某个点。

0 0
原创粉丝点击