牛客练习赛74 CCA的图(并查集贪心)
CCA的数列
https://ac.nowcoder.com/acm/contest/9700/A
本来不算裸题,但是这个数据范围提示的太明显了
先对边按照编号排序
先保证最大
那么我们的边从一直并查集合并,一旦
连通就停下来
那么这个一定是最大的
现在我们要求最小
那我们把并查集数组再次初始化,按顺序加边
一旦连通就停下来,此时是最小的
正确性显然....(不显然可以留言)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
struct edge{
    int l,r,w;
    bool operator < (const edge&tmp )    const{
        return w<tmp.w;
    }
}a[maxn*3];
int n,pre[maxn],m,s,t,ansl,ansr;
int find(int x){ return x==pre[x]?x:pre[x]=find(pre[x]);}
void join(int q,int w)
{
    pre[find(q)] = find(w);
}
int main()
{
    cin >> n >> m >> s >> t;
    for(int i=1;i<=n;i++)    pre[i] = i;
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].w);
    sort( a+1,a+1+m );
    for(int i=m;i>=1;i--)
    {
        int l = a[i].l, r = a[i].r;
        join(l,r);
        if( find(s)==find(t) )
        {
            ansl = i;
            break;
        }
    }
    for(int i=1;i<=n;i++)    pre[i] = i;
    for(int i=ansl;i<=m;i++)
    {
        int l = a[i].l, r = a[i].r;
        join(l,r);
        if( find(s)==find(t) )
        {
            ansr = i;
            break;
        }        
    }
    cout << a[ansl].w << " " << a[ansr].w;
} 

