传送门:https://www.luogu.org/problemnew/show/P1525
这个题目比较复杂,比较难联系到各种算法上。
但是!既然是划分集合,不如用并查集来搞一搞吧!
思路:有句老话说得好,敌人的敌人是朋友。我们先将关系排个序,然后for一遍关系,如果一个x和y在一个集合里面,那就直接输出结果就好了,如果不在一个集合里面,那我们就把x的敌人和y放在集合里面,把y的敌人和x放在集合里面,因为敌人的敌人是朋友嘛,所以这样就是最小的啦!
这样真的就AC了鸭,for多写了一个,说明不存在的时候输出了一个0
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int match[maxn];
struct node
{
int x;
int y;
int w;
}q[maxn];
bool cmp(node a,node b)
{
return a.w>b.w;
}
int p[maxn],r[maxn];
void init()
{
for(int i=0;i<maxn;i++)
{
p[i] = i;
r[i] = 0;
}
}
int find(int x)
{
if(p[x]==x) return x;
return p[x] = find(p[x]);
}
void unite(int x,int y)
{
x = find(x);
y = find(y);
if(x==y) return;
if(r[x]<r[y])
{
p[x] = y;
}
else
{
p[y] = x;
if(r[x]==r[y])
{
r[x]++;
}
}
}
bool same(int x,int y)
{
return find(x)==find(y);
}
int main()
{
int n,m;
cin>>n>>m;
init();
for(int i=0;i<m;i++)
{
cin>>q[i].x>>q[i].y>>q[i].w;
}
sort(q,q+maxn,cmp);
for(int i=0;i<=m;i++)
{
if(same(q[i].x,q[i].y))
{
cout<<q[i].w<<endl;
break;
}
else
{
if(!match[q[i].x]) match[q[i].x] = q[i].y;
else unite(match[q[i].x],q[i].y);
if(!match[q[i].y]) match[q[i].y] = q[i].x;
else unite(match[q[i].y],q[i].x);
}
}
return 0;
}