洛谷P1396 营救

题目链接:https://www.luogu.com.cn/problem/P1396

不太寻常的生成树问题,

这个题可以理解为最短路跑图,也可以理解为最小生成树找起点和终点的集合问题,

此题的解法多种,常见的是:dijkstra,kruskal,kruskal重构树问题,树上问题求解,二分并查集求解,当然

最简单的还是纯kruskal;

但这个题不完全是kruskal,因为这个题要求给出拥挤度的最小

"所以请你帮她规划一条从 s 至 t 的路线,使得经过道路的拥挤度最大值最小"。

什么意思呢,当然,这个题可不是求生成树的值哈;

这个题是从头开始跑,判断起点s和终点t是否联通,如果联通了就立马输出当前的权值,这个时候的拥挤度就是最小的,因为

1.满足了条件,从s可以到t;

2.最小生成树按边权值排序了,从小取到大,这时候输出必定是最小的。

当然,这个题用最短路跑是一点问题都没有的,尤其是用dijkstra。

spfa的话我就不确定了。

然后这个题按MST跑图,联通了输出就🆗了;

再次嘱咐:

不是求MST,

不是求MST,

不是求MST

Talk is cheap. Show me the code.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m;
 4 const int num=1e5+10;
 5 struct edge
 6 {
 7     int u;
 8     int v;
 9     int w;
10 }e[num];
11 int ans;
12 int st,t;
13 int s[num];
14 bool cmp(edge a,edge b)
15 {
16     return a.w<b.w;
17 }
18 int find_set(int x)
19 {
20     if(x!=s[x])
21     {
22         s[x]=find_set(s[x]);
23     }
24     return s[x];
25 }
26 void kruskal()
27 {
28     for(register int  i=1;i<=n;i++)
29     {
30         s[i]=i;
31     }
32     sort(e+1,e+1+m,cmp);
33     for(register int i=1;i<=m;i++)
34     {
35         int b=find_set(e[i].u);
36         int c=find_set(e[i].v);
37         if(b==c)
38         {
39             continue;
40         }
41         s[c]=b;
42         ans+=e[i].w;
43         if(find_set(st)==find_set(t))//首次联通直接输出即可
44         {
45             cout<<e[i].w<<endl;
46             break;
47         }
48     }//这里不必在进行cnt判断,这不是判断最小生成树的不连通性
49 }
50 int main()
51 {
52     std::ios::sync_with_stdio(false);
53     cin>>n>>m>>st>>t;
54     for(register int i=1;i<=m;i++)
55     {
56         cin>>e[i].u>>e[i].v>>e[i].w;
57     }
58     kruskal();
59     return 0;
60 }

 

posted @ 2022-04-30 15:46  江上舟摇  阅读(22)  评论(0编辑  收藏  举报