聯絡員(最小生成樹)

2021-07-11 02:51:28 字數 3157 閱讀 1828

description

tyvj已經一歲了,**也由最初的幾個使用者增加到了上萬個使用者,隨著tyvj**的逐步壯大,管理員的數目也越來越多,現在你身為tyvj管理層的聯絡員,希望你找到一些通訊渠道,使得管理員兩兩都可以聯絡(直接或者是間接都可以)。tyvj是乙個公益性的**,沒有過多的利潤,所以你要盡可能的使費用少才可以。 目前你已經知道,tyvj的通訊渠道分為兩大類,一類是必選通訊渠道,無論**多少,你都需要把所有的都選擇上;還有一類是選擇性的通訊渠道,你可以從中挑選一些作為最終管理員聯絡的通訊渠道。資料保證給出的通行渠道可以讓所有的管理員聯通。

input

第一行n,m表示tyvj一共有n個管理員,有m個通訊渠道第二行到m+1行,每行四個非負整數,p,u,v,w 當p=1時,表示這個通訊渠道為必選通訊渠道;當p=2時,表示這個通訊渠道為選擇性通訊渠道;u,v,w表示本條資訊描述的是u,v管理員之間的通訊渠道,u可以收到v的資訊,v也可以收到u的資訊,w表示費用。

output

最小的通訊費用

sampleinput

sample output

5 6
1 1 2 1
1 2 3 1
1 3 4 1
1 4 1 1
2 2 5 10
2 2 5 5
hint

樣例解釋: 

1-2-3-4-1存在四個必選渠道,形成乙個環,互相可以到達。需要讓所有管理員聯通,需要聯通2和5號管理員,選擇費用為5的渠道,所以總的費用為9 

注意: 

u,v之間可能存在多條通訊渠道,你的程式應該累加所有u,v之間的必選通行渠道 

資料範圍: 

對於30%的資料,n<=10 m<=100 

對於50%的資料, n<=200 m<=1000 

對於100%的資料,n<=2000m<=10000 

先把必選通訊渠道合併,用並查集打最小生成樹。

var
p,r:array [1..2001] of longint;
a:array [1..10001,1..3] of longint;
n,m,p1,u,v,w,ans,k,i:longint;
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);
if u=v then exit;
if r[u]<=r[v] then
begin
p[u]:=v;
if r[u]=r[v] then inc(r[v]);
end
else 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]
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,m);
for i:=1 to m do
begin
readln(p1,u,v,w);
if p1=1 then
begin
ans:=ans+w;
union(u,v);
end
else
begin
inc(k);
a[k,1]:=u;
a[k,2]:=v;
a[k,3]:=w;
end;
end;
qsort(1,k);
for i:=1 to k do
begin
if find(a[i,1])<>find(a[i,2]) then
begin
union(a[i,1],a[i,2]);
ans:=ans+a[i,3];
end;
end;
write(ans);
end.

TYVJ 1307 聯絡員(最小生成樹)

kruskal裸題。水題紅色警報 include include include include include include using namespace std define rep i,n for int i 0 i define for1 i,a,n for int i a i n i ...

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

最小生成樹

package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...