题目大意:
S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件。
每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S城Z市长那里。公务繁忙的Z市长只会去看列表中的第一个事件的影响力,如果影响很坏,他就会考虑撤换警察局长。
在详细考察了N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。
那么,应如何分配罪犯,才能使Z 市长看到的那个冲突事件的影响力最小?这个最小值是多少?
题解:
排序+并查集:
这题我们分析可得要求的是最大的冲突最小是多少
怎么做呢?
先将其的怨恨度大到小排序,
然后做并查集
对于一组罪犯i,j如果他们放到不同监狱中跟之前冲突了,那么他们的冲突影响肯定是答案
因为如果不让他们2个冲突,那么比他们大的冲突影响就会冲突
判断过程用并查集去存即可。
代码:
var
a:array [0..100001,1..3] of longint;
f:array [0..40001] of longint;
i,j,p,q,n,m:longint;
procedure qsort(l,r:longint);
var
i,j,mid:longint;
begin
if l>=r then exit;
mid:=a[(l+r) div 2,3];
i:=l; j:=r;
repeat
while a[i,3]>mid do inc(i);
while a[j,3]<mid do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i); dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
function find(x:longint):longint;
begin
if f[x]=x then exit(x);
f[x]:=find(f[x]);
exit(f[x]);
end;
begin
readln(n,m);
for i:=1 to m do
begin
for j:=1 to 3 do read(a[i,j]);
readln;
end;
qsort(1,m);
for i:=1 to 2*n do f[i]:=i;
for i:=1 to m do
begin
p:=find(a[i,1]);
q:=find(a[i,2]);
f[p]:=find(a[i,2]+n);
f[q]:=find(a[i,1]+n);
if p=q then
begin
writeln(a[i,3]);
halt;
end;
end;
writeln(0);
end.