题解1:
按边权从大到小排序,如果这条边的两个点没确定关系,那么把他们设为敌人
这样,就成了一棵棵最大生成树(因为有的罪犯之间没有怨气)
由敌人的敌人是朋友可以得出,如果两个点在同一棵树,且距离为偶数,那么代表他们之间互为朋友
code1
#include<bits/stdc++.h>
using namespace std;
struct unit
{
int x,y,v;
bool operator<(const unit &b) const {return v>b.v;}
}edge[100005];
int fa[20005]={0};
int depth[20005]={0};
vector<int> G[20005];
int finds(int now){return fa[now]=(fa[now]==now?now:finds(fa[now]));}
void ss(int now,int f)
{
for(auto next:G[now])
if(next!=f)
{
depth[next]=depth[now]+1;
ss(next,now);
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>edge[i].x>>edge[i].y>>edge[i].v;
for(int i=1;i<=n;i++) fa[i]=i;
sort(edge+1,edge+1+m);
int ans=0;
for(int i=1;i<=m;i++)
{
int x=edge[i].x,y=edge[i].y;
if(finds(x)!=finds(y))//如果两者之间没有确定关系,确定为敌人关系
{
fa[finds(x)]=finds(y);
G[x].push_back(y);
G[y].push_back(x);
}
}
for(int i=1;i<=n;i++)
if(!depth[i])//并不是所有罪犯之间都有仇恨
{
depth[i]=1;
ss(i,0);
}
for(int i=1;i<=m;i++) if((depth[edge[i].x]^depth[edge[i].y])%2==0) ans=max(ans,edge[i].v);//如果是同号,即两者距离为偶数
cout<<ans;
return 0;
}
标签:P1525,关押,int,NOIP2010,next,fa,20005,edge,now
From: https://www.cnblogs.com/pure4knowledge/p/18059532