Description
你在玩电子游戏的时候遇到了麻烦。。。。。。 你玩的游戏是在一个虚拟的城市里进行,这个城市里有n个点,都从0~n-1编了号,每两个点之间有且仅有一条路径。现在,你的敌人到这个城市来踩点了!!!为了阻止他们更好的踩点, 你决定切断他们所有踩点人员的联系,使他们孤军作战,然后在各个击破。但是这就要切断某些街道,而你每切断一条路,市民就会产生相对的不满值,不满值越大,城市的和谐度就越小。所以你现在需要知道为了使踩点人员所在的点两两之间不联通所切断的边产生的最小不满值是多少?
Input
第一行一个数:nn<=50 以下n-1行,每行3个数 a,b,c 表示a点和b点之间有条路,切断这条路的不满值为c 以下若干行 每行一个数,表示踩点人员的位置
Output
一个数,最小不满值
Sample Input
5
1 0 1
1 2 2
0 3 3
4 0 4
3 2 4
Sample Output
4
分析:
并查集,把不满值多的边先插进去,再判断有没有踩点人员可以联系。
代码:
var
c,p,p1,b:Array [0..100] of longint;
a:array [0..100,0..3] of longint;
n,i,j,ans,k,t,x:longint;
flag:boolean;
function find(x:longint):longint;
var y,root,w:longint;
begin
y:=x;
while p[y]>0 do
y:=p[y];
root:=y;
y:=x;
while p[y]>0 do
begin
w:=p[y];
p[y]:=root;
y:=w;
end;
find:=root;
end;
procedure union(x,y:longint);
var
u,v:longint;
begin
u:=find(x);
v:=find(y);
p[v]:=u;
end;
procedure qsort(l,r:longint);
var
i,j,key,temp:longint;
begin
if l>=r then exit;
i:=l;j:=r;
key:=a[l+random(r-l+1),3];
repeat
while (a[i,3]>key) do inc(i);
while (a[j,3]<key) do dec(j);
if i<=j then
begin
temp:=a[i,1];a[i,1]:=a[j,1];a[j,1]:=temp;
temp:=a[i,2];a[i,2]:=a[j,2];a[j,2]:=temp;
temp:=a[i,3];a[i,3]:=a[j,3];a[j,3]:=temp;
inc(i);dec(j);
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
begin
readln(n);
for i:=1 to n-1 do
begin
read(a[i,1],a[i,2],a[i,3]);
ans:=ans+a[i,3];
end;
qsort(1,n-1);
while not eof do
begin
inc(t);
readln(x);
c[t]:=x;
end;
for i:=1 to n-1 do
begin
ans:=ans-a[i,3];
p1:=p;
union(a[i,1]+1,a[i,2]+1);
flag:=true;
for j:=1 to t do
b[j]:=find(c[j]+1);
for j:=1 to t-1 do
for k:=j+1 to t do
if b[j]=b[k] then flag:=false;
if not flag then
begin
p:=p1;
ans:=ans+a[i,3];
end;
end;
writeln(ans);
end.
这里写代码片