标签:
S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极
不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨
气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之
间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并
造成影响力为c 的冲突事件。
每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,
然后上报到S 城Z 市长那里。公务繁忙的Z 市长只会去看列表中的第一个事件的影响力,
如果影响很坏,他就会考虑撤换警察局长。
在详细考察了N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在
两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只
要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那
么,应如何分配罪犯,才能使Z 市长看到的那个冲突事件的影响力最小?这个最小值是少?
第一行为两个正整数N 和M,分别表示罪犯的数目以及存在仇恨的罪犯对数。
接下来的M 行每行为三个正整数aj,bj,cj,表示aj 号和bj 号罪犯之间存在仇恨,其怨气值为cj。数据保证,且每对罪犯组合只出现一次。
共1 行,为Z 市长看到的那个冲突事件的影响力。如果本年内监狱
中未发生任何冲突事件,请输出0。
4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884
3512
罪犯之间的怨气值如下面左图所示,右图所示为罪犯的分配方法,市长看到的冲突事件
影响力是3512(由2 号和3 号罪犯引发)。其他任何分法都不会比这个分法更优。
对于30%的数据有N≤ 15。
对于70%的数据有N≤ 2000,M≤ 50000。
对于100%的数据有N≤ 20000,M≤ 100000。
该题是一个并查集的变形应用(当然还有其他更高级的算法,但很可惜我不会),将怨气值从大到小排序(类似最小生成树中克鲁斯卡尔算法),将怨气值较大的两个人放到不同的集合中,不断向下进行,知道找到第一组人在前面的操作中已经被放到同一个集合中,输出怨气值,退出
1 program prison; 2 type peo=record 3 x,y,w:longint; 4 end; 5 var 6 pe:array[0..100000] of peo; 7 b,f:Array[0..20000] of longint; 8 fa,fb,i,j,n,m:longint; 9 function root(x:longint):Longint; 10 begin 11 if f[x]=x then exit(x); 12 root:=root(f[x]); 13 f[x]:=root; 14 exit(root); 15 end; 16 17 procedure sort(l,r: longint); 18 var 19 i,j,x,y: longint; 20 begin 21 i:=l; 22 j:=r; 23 x:=pe[(l+r) div 2].w; 24 repeat 25 while pe[i].w>x do 26 inc(i); 27 while x>pe[j].w do 28 dec(j); 29 if not(i>j) then 30 begin 31 pe[0]:=pe[i]; 32 pe[i]:=pe[j]; 33 pe[j]:=pe[0]; 34 inc(i); 35 j:=j-1; 36 end; 37 until i>j; 38 if l<j then 39 sort(l,j); 40 if i<r then 41 sort(i,r); 42 end; 43 begin 44 fillchar(b,sizeof(b),0); 45 read(n,m); 46 for i:=1 to n do f[i]:=i; 47 for i:=1 to m do read(pe[i].x,pe[i].y,pe[i].w); 48 sort(1,m); 49 for i:=1 to m do 50 begin 51 fa:=root(pe[i].x); 52 fb:=root(pe[i].y); 53 begin 54 if fa=fb then//判断 55 begin 56 writeln(pe[i].w); 57 halt; 58 end 59 else 60 begin 61 if b[pe[i].x]=0 then 62 begin 63 b[pe[i].x]:=pe[i].y;//如果x没有敌人,就把y作为敌人 64 end; 65 if b[pe[i].y]=0 then 66 begin 67 b[pe[i].y]:=pe[i].x; 68 end; 69 f[root(b[pe[i].x])]:=root(pe[i].y);//合并x与y的敌人 70 {只有两个监狱,非此即彼} 71 f[root(b[pe[i].y])]:=root(pe[i].x); 72 end; 73 end; 74 end; 75 writeln(0); 76 end.
标签:
原文地址:http://www.cnblogs.com/wuminyan/p/4735471.html