罪犯之间的怨气值如下面左图所示,右图所示为罪犯的分配方法,市长看到的冲突事件
影响力是3512(由2 号和3 号罪犯引发)。其他任何分法都不会比这个分法更优。
对于30%的数据有N≤ 15。
对于70%的数据有N≤ 2000,M≤ 50000。
对于100%的数据有N≤ 20000,M≤ 100000。
按怨气值从大到小排序,依次把两个人放到不同的集合中,直到出现矛盾为止。
只有两个监狱,所以多开一倍数组,用f[n+1~2*n] 表示f[1~n]的补集 (就是另一个监狱)
合并的时候 root(a) = root(f[b+n]) ,就是把a 和 b的补集(就是a的监狱)合并了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 20010
#define M 100010
using namespace std;
struct node
{
int a,b,c;
}e[M];
int n,m;
int cmp(const node &a, const node &b)
{
return a.c>b.c;
}
int f[N*2];
int root(int x)
{
f[x]==x?x:f[x] = root(f[x]);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n*2;i++) f[i] = i;
for (int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
sort(e+1,e+m+1,cmp);
for (int i=1;i<=m;i++)
{
int x = root(e[i].a), y = root(e[i].b);
if (x == y)
{
printf("%d",e[i].c);
return 0;
}
f[x] = root(e[i].b+n);
f[y] = root(e[i].a+n);
}
printf("0");
return 0;
}