快排+贪心+并查集
过程:
从大到小快排一遍,因为要求最大怨气值最小,所以每次要删除边,然后分成两个集合。
对于之前没有确定关系的两个人,分别确定这两个人为敌人关系(因为数据从大到小保证有序),所以一定不能把他们放在同一监狱。
对于之前某个人已经确定关系,则让未确定关系的人和已确定关系的人的敌人同属一个集合,让未确定关系的人的敌人和已确定关系的人同属一个集合。
如果两个人的祖先相同,那么这条边一定是最大的怨气值,输出即可。(因为数据保证有序了。)
program prison;
type date=record
l,r,v:longint;
end;
var
a:array[1..100000]of date;
fa:array[1..20000]of longint;
dui:array[1..20000]of longint;
n,m,i,j,ans:longint;
procedure qsort(he,ti:longint);
var
i,j,x:longint;
y:date;
begin
i:=he;
j:=ti;
x:=a[(i+j)>>1].v;
repeat
while a[i].v<x do inc(i);
while a[j].v>x do dec(j);
if i<=j then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
i:=i+1;
j:=j-1;
end;//if
until i>j;//repeat
if he<j then qsort(he,j);
if i<ti then qsort(i,ti);
end;//qsort
function find(x:longint):longint;
begin
if fa[x]=x then exit(x);
fa[x]:=find(fa[x]);
exit(fa[x]);
end;//find
procedure union(a,b:longint);
begin
fa[find(a)]:=find(fa[b]);
end;//union
begin
fillchar(fa,sizeof(fa),0);
readln(n,m);
for i:=1 to n do fa[i]:=i;
for i:=1 to m do readln(a[i].l,a[i].r,a[i].v);
qsort(1,m);
i:=m;
while i>0 do
begin
if find(a[i].l)=find(a[i].r) then
begin
ans:=a[i].v;
break;
end;
if (dui[a[i].l]=0) and (dui[a[i].r]=0) then
begin
dui[a[i].l]:=a[i].r;
dui[a[i].r]:=a[i].l;
end
else
begin
if dui[a[i].l]<>0 then
begin
union(dui[a[i].l],a[i].r);
if dui[a[i].r]=0 then dui[a[i].r]:=a[i].l;
end;
if dui[a[i].r]<>0 then
begin
union(dui[a[i].r],a[i].l);
if dui[a[i].l]=0 then dui[a[i].l]:=a[i].r;
end;
end;
dec(i);
end;
writeln(ans);
end.