您的位置:首页 > 其它

NOIP2010 关押罪犯

2012-10-28 11:41 197 查看
http://vijos.org/p/1776


描述 Description
S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件。
每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z 市长那里。公务繁忙的Z 市长只会去看列表中的第一个事件的影响力,如果影响很坏,他就会考虑撤换警察局长。
在详细考察了N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那么,应如何分配罪犯,才能使Z 市长看到的那个冲突事件的影响力最小?这个最小值是多少?

输入格式 InputFormat
输入文件的每行中两个数之间用一个空格隔开。
第一行为两个正整数N 和M,分别表示罪犯的数目以及存在仇恨的罪犯对数。
接下来的M 行每行为三个正整数aj,bj,cj,表示aj 号和bj 号罪犯之间存在仇恨,其怨气值为cj。数据保证1<=aj<bj<N,0<cj<=1,000,000,000 且每对罪犯组合只出现一次。

输出格式 OutputFormat
输出共1 行,为Z 市长看到的那个冲突事件的影响力。如果本年内监狱中未发生任何冲突事件,请输出0。

样例输入 SampleInput
4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884

样例输出 SampleOutput
3512

数据范围和注释 Hint
对于30%的数据有N≤ 15。
对于70%的数据有N≤ 2000,M≤ 50000。
对于100%的数据有N≤ 20000,M≤ 100000。

时间限制 TimeLimitation
各个测试点1s

解题报告
基于一个数不在另一个数的集合中,则必在其补集中的事实,以及本题中两个数同时在同一个数的补集中,则必定在对方的集合中的事实,可以构造两个并查集,分别表示i的集合与补集。之后将边按边权从大到小排序,依次将起点与终点添加到对方补集中。当出现矛盾时,即当前边的起点和终点都属于同一个点的补集,则当前边的权值即为所求。
代码中将a[n+1..2*n]作为点1..n的补集。

代码

View Code

type
qxx=record
st,en,len:longint;
end;
var
a:array[1..40001]of longint;
e:array[1..100000]of qxx;
m,n,i,j,k,l:longint;
function get_f(p:longint):longint;
var
q:longint;
begin
q:=p;
while a[p]<>p do p:=a[p];
get_f:=p;
p:=q;
while a[q]<>get_f do begin
q:=a[q];
a[p]:=get_f;
p:=q;
end;
end;
procedure mapinput(x:longint);
var
r,s,t:longint;
begin
read(r,s,t);
e[x].st:=r;
e[x].en:=s;
e[x].len:=t;
end;
procedure qsort(ll,rr:longint);
var
l,r,x,y:longint;
begin
l:=ll;
r:=rr;
x:=e[(l+r)shr 1].len;
repeat
while e[l].len>x do inc(l);
while e[r].len<x do dec(r);
if l<=r then begin
y:=e[l].len;
e[l].len:=e[r].len;
e[r].len:=y;
y:=e[r].st;
e[r].st:=e[l].st;
e[l].st:=y;
y:=e[r].en;
e[r].en:=e[l].en;
e[l].en:=y;
inc(l);
dec(r);
end;
until l>r;
if (l<rr) then qsort(l,rr);
if (r>ll) then qsort(ll,r);
end;
begin
read(n,m);
for i:=1 to 2*n do a[i]:=i;
for i:=1 to m do mapinput(i);
qsort(1,m);
j:=1;
while (j<=m) do begin
if get_f(e[j].st)=get_f(e[j].en) then begin
writeln(e[j].len);
break;
end;
if get_f(e[j].st)<>get_f(e[j].en+n) then a[get_f(e[j].st)]:=get_f(e[j].en+n);
if get_f(e[j].en)<>get_f(e[j].st+n) then a[get_f(e[j].en)]:=get_f(e[j].st+n);
inc(j);
end;
if j>m then writeln('0');
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: