修复公路

题目链接:https://www.luogu.org/problemnew/show/P1111

显而易见,这道题目使用的是并查集与生成树,查询x村庄和y村庄时候相连

-1的情况也很好判断(我用了一种很自己认为弱智的算法进行判断)

还有一个问题,怎样求出最小的各点全连通的时间

可以考虑以下思路:将各个道路按照建造的时间排序,每次combine两个村庄的时候就可以更新当前的时间,当前时间即为“最早各点连通时间”【因为两点连通过后下次的判断可以直接跳过,不考虑建造这条道路,由此可知此算法正确】

以下是代码:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 using namespace std;
 7 const int N=1005;
 8 int t[N][N],father[N];
 9 int find(int x)
10 {
11     if(father[x]!=x)
12     father[x]=find(father[x]);
13     return father[x];
14 }
15 void combine(int x,int y)
16 {
17     int t1,t2;
18     t1=find(x);
19     t2=find(y);
20     if(t1!=t2)
21     father[t1]=t2;
22 }
23 struct build
24 {
25     int tm,x,y;
26 }a[100005];
27 bool cmp(build p,build q)
28 {
29     return p.tm<q.tm;
30 }
31 int n,m;
32 int main()
33 {
34     int x,y,tm,minn;
35     cin>>n>>m;
36     for(int i=1;i<=n;++i)
37     father[i]=i;
38     for(int i=1;i<=m;++i)
39     cin>>a[i].x>>a[i].y>>a[i].tm;
40     sort(a+1,a+m+1,cmp);
41     for(int i=1;i<=m;++i)
42     {
43         if(find(a[i].x)!=find(a[i].y))
44         {
45             minn=a[i].tm;
46             combine(a[i].x,a[i].y);
47         }
48     }
49     for(int i=2;i<=n;++i)
50     {
51         if(find(1)!=find(i))
52         {
53             cout<<"-1"<<endl;
54             return 0;
55         }
56     }
57     cout<<minn<<endl;
58     return 0;
59 }

 

总结:遇到此类(如同连通块、并查集等)求各点全连通的题目,可以考虑对时间(价值)进行排序以求出最小时间。

posted @ 2019-07-05 20:14  LyingFlat666  阅读(132)  评论(0编辑  收藏  举报