uva 1599 ideal path(好题)——yhx

 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,最后求出来的就一定是最短路。

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

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

posted @ 2016-03-20 22:31  Orion_7  阅读(217)  评论(0编辑  收藏  举报