演算法:圖論(最小生成樹)
分析:題目大意在tyvj上說的不是很清楚,這裡再說明一下,就是說給出了乙個不完全圖(最小生成樹),在這個不完全圖中新增邊使之成為完全圖,同時新增完邊之後必須能保證不破壞原來的最小生成樹。
可以採用kruskal解決,我們知道kruskal的最終目的是將兩棵最小生成樹合成一棵,設第一棵樹中點的個數為x,第二課樹中點的個數為y,那麼除去他們之間連線的最短的邊,一定還有x*y-1條邊,所以就讓這x*y-1條邊的權值為兩顆樹之間連線的最短的邊的權值+1。
乙個更通俗的解釋就是,不在生成樹內的邊一定大於在生成樹內的邊。
最後用所有邊的邊權和減去最小生成樹的邊權和就是修建道路的費用和。
program p1391;
const
maxn=6000;
type
atp=record
x,y,dis:longint;
end;
var ans,sum,total,ii,n:longint;
a:array [0..maxn] of atp;
v,fa:array [0..maxn] of longint;
procedure init;
var i,x,y,dis:longint;
begin
ans:=0;
sum:=0;
readln(n);
for i:=1 to n-1 do
begin
fa[i]:=i;
v[i]:=1;
readln(x,y,dis);
inc(sum,dis);
a[i].x:=x;
a[i].y:=y;
a[i].dis:=dis;
end;
fa[n]:=n;
v[n]:=1;
end;
function getf(x:longint):longint;
begin
if fa[x]=x then exit(x)
else
begin
fa[x]:=getf(fa[x]);
exit(fa[x]);
end;
end;
procedure qsort(l,r:longint);
var i,j,m:longint;
t:atp;
begin
i:=l;
j:=r;
m:=a[(l+r) shr 1].dis;
repeat
while a[i].dism do dec(j);
if i<=j then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if i
tyvj 1391 走廊潑水節
p1391 走廊潑水節 背景話說,中中帶領的oier們打算舉行一次冬季潑水節,當然這是要秘密進行的,絕對不可以讓中中知道。不過中中可是 湖了,當然很快就發現了我們的小陰謀,於是他準備好水槍迫不及待的想要加入我們了。描述我們一共有n個oier打算參加這個潑水節,同時很湊巧的是正好有n個水龍頭 至於為什...
tyvj1391走廊潑水節 kruskal
題目 大意就是把乙個樹擴充成乙個完全圖,並且圖中最小生成樹仍是原來的樹。思路很巧妙,把邊按權值從小到大排序,然後模擬加邊的過程,並查集記錄左右兩邊連通塊的大小 這樣每新加一條邊合併兩個並查集 完全圖 可知此時兩邊的圖中每個點互相連邊的最優選擇就是連線這兩個圖的那條邊的邊權 1 這樣求最小生成樹時要連...
TYVJ 1391 走廊潑水節 生成樹
鏈結太長放不下 給定一棵n nn個節點的樹,要求增加若干條邊,把這棵樹擴充為完全圖,並完全圖的唯一最小生成樹仍然是這棵樹。求增加的邊的權值總和最小是多少。資料範圍 n 6000 n leq6000 n 6000 原有的邊權均為非負整數 首先題目要求完全圖的唯一最小生成樹仍然是這棵樹,所以對於對兩個點...