Heavy Transportation POJ - 1797

原题链接

考察:最小生成树或最短路

这类题型感觉终于搞懂了一点...蒟蒻落泪

这里还有道和本题差不多的题GO

思路:

       我们要让最小边权最大,也就是我们尽量走权大的边.spfa更新dist数组时,要赋值大值.但同时我们也需要让这条路径边权最小,也就是这条语句:

dist[i]<min(g[t][i],dist[t])

min保证是此前路径的最小边.<保证是到达此点的最小边权尽量大.

此外注意一下初始化:dist[i]除了1外全部为0,dist[1]需要赋值0x3f3f3f3f,否则更新不了队列

 1 #include <iostream>
 2 #include <queue>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 1010;
 6 int g[N][N],n,m,dist[N];
 7 bool st[N];
 8 void spfa()
 9 {
10     queue<int> q;
11     q.push(1);
12     st[1] = 1;
13     for(int i=1;i<=n;i++) dist[i] = 0;
14     dist[1] = 0x3f3f3f3f;
15     while(q.size())
16     {
17         int t = q.front();
18         st[t] = 0;
19         q.pop();
20         for(int i=1;i<=n;i++)
21         {
22             if(dist[i]<min(g[t][i],dist[t]))
23             {
24                 dist[i] = min(g[t][i],dist[t]);
25                 if(!st[i]) q.push(i),st[i] = 1;
26             }
27         }
28     }
29 }
30 int main()
31 {
32     int T,kcase = 0;
33     scanf("%d",&T);
34     while(T--)
35     {
36         fill(st,st+N,0);
37         printf("Scenario #%d:\n",++kcase);
38         scanf("%d%d",&n,&m);
39         memset(g,0,sizeof g);
40         while(m--)
41         {
42             int x,y,z;
43             scanf("%d%d%d",&x,&y,&z);
44             g[x][y] = g[y][x] =  z;
45         } 
46         spfa();
47         printf("%d\n\n",dist[n]);
48     }
49     return 0; 
50 }
spfa最短路

 

最小生成树的思路:
        边要按权大的排序.当n与1在一个集合里,就可以跳出

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 const int N = 1010;
 5 struct Edge{
 6     int x,y,w;
 7     bool operator<(Edge t){
 8         return this->w<t.w;
 9     }
10 }edge[N*N>>1];
11 int n,m,p[N];
12 int findf(int x)
13 {
14     if(x!=p[x]) p[x] = findf(p[x]);
15     return p[x];
16 }
17 void inits()
18 {
19     for(int i=1;i<=n;i++) p[i] = i;
20 }
21 int main()
22 {
23 //    freopen("in.txt","r",stdin);
24     int T;
25     scanf("%d",&T);
26     for(int i=1;i<=T;i++)
27     {
28         printf("Scenario #%d:\n",i);
29         scanf("%d%d",&n,&m);
30         inits();
31         for(int j=1;j<=m;j++)
32         {
33             int x,y,w; scanf("%d%d%d",&edge[j].x,&edge[j].y,&edge[j].w);
34         }
35         sort(edge+1,edge+m+1);
36         for(int j=m;j>0;j--)
37         {
38             int px = findf(edge[j].x),py = findf(edge[j].y);
39             if(px!=py)
40             {
41                 p[px] = py;
42                 if(findf(1)==findf(n)) { printf("%d\n\n",edge[j].w); break;} 
43             }
44         } 
45     }
46     return 0;
47 }
最小生成树

 

posted @ 2021-01-20 16:37  acmloser  阅读(37)  评论(0编辑  收藏  举报