2022河南萌新联赛第(五)场:B.交通改造(并查集)

https://ac.nowcoder.com/acm/contest/38718/B

题目描述 
A城是一座繁忙又有活力的城市,随着城市的发展,原有的道路越发拥堵,所以政府决定对原有的道路交通系统进行改造。

A城目前的道路是这样的:城市中有n个交叉路口,部分交叉路口通过道路直接相连,任意两个交叉路口之间最多有一条道路连接。A城的只有双向道,没有单向道,并且所有交叉路口都通过道路直接或间接相连。现在给每条道路设定一个通畅值,通畅值越小则该道路越繁忙也越需要改造。出于节约资金的思想考虑,现在政府希望改造的道路尽可能少,于是提出了下列要求:接受改造的道路能够令所有的交叉路口直接或间接相连,并且改造的道路数量应尽可能的少,其次在满足上述条件的情况下,令被改造的道路中通畅值最大的道路的通畅值尽量小。


现在你作为政府的顾问,请设计一套方案,确定哪些道路需要被改造。

输入描述:
第一行有两个整数n,m表示城市有n个交叉路口,m条道路。

接下来m行是对每条道路的描述,u, v,c表示交叉路口u和v之间有道路相连,分值为c。

输出描述:
两个整数s,max,表示你选出了几条道路,分值最大的那条道路的分值是多少。
示例1
输入
4 5
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8
复制
3 6
  1. 题目意思简化版:给定n个点,m条双向边,每条双向边带一个权值。权值越小,越需要改造,权值越大,越不需要。

  2. 要求是:接受改造的道路能够和所有的交叉路口直接或间接相连,这就说明了所有的节点都必须连一个集合里面;

  3. 并且改造的道路数量应尽可能的少,能最小化连接成集合的数量,连完就跑路。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200200,M=2002;
int father[N];
struct node
{
    int x;
    int y;
    int z;
}a[N];
bool cmp(node l,node r)
{
    return l.z<r.z;
}
int find(int x)
{
    if(father[x]!=x) father[x]=find(father[x]);
    return father[x];
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>a[i].x>>a[i].y>>a[i].z;
        }
        //通畅值越小则该道路越繁忙也越需要改造
        sort(a+1,a+1+m,cmp);
        for(int i=1;i<=n;i++)
            father[i]=i;
        int flag=0,ans=0;
        for(int i=1;i<=m;i++)
        {
            //接受改造的道路能够令所有的交叉路口直接或间接相连
            int fa=find(a[i].x),fb=find(a[i].y);
            //所以一旦发现有需要粘在一起的,就得黏在一起
            //不然的话就换下一个
            if(fa!=fb)
            {
                flag++;
                father[fa]=fb;
                if(flag==n-1)
                {
                    ans=a[i].z;
                    break;
                }
            }
        }
        cout<<n-1<<" "<<ans<<endl;//n个点需要构成一棵树,肯定是需要连接n-1条边的
    }
    return 0;
}
posted @ 2022-08-12 11:37  Vijurria  阅读(100)  评论(0编辑  收藏  举报