兔
時間限制: 1 sec 記憶體限制: 128 mb
[提交] [狀態]
題目描述
小粉兔用集訓隊的獎金買下了一片地。
這片地上有 n 個房子,有些房子之間有道路,有些房子之間則是雜草。
她可以花費一定的代價拆毀一條道路,或是啃光一片草使得兩個房子間可以通行(大霧)。
她喜歡生成樹,所以她要讓所有道路形成一棵生成樹。
求最小花費。
輸入第一行乙個數,n。
接下來 n 行,每行 n 個數,代表 ai,j。如果為正數,說明它們之間沒有道路,需要 ai,j的花費來修建;如果為負數,說明它們之間有道路,需要 −ai,j的花費來拆毀。
輸出一行乙個數,代表最小花費。
樣例輸入 copy
30 1 -3
1 0 5
-3 5 0
樣例輸出 copy1提示
對於 100% 的資料,5≤n≤1000,1≤|ai,j(i≠j)|≤1000,保證所有 ai,i=0且 ai,j=aj,i 。
題意就是讓你在給定條件下,生成一棵樹,可以在某些點之間建邊,也可以刪給定的邊。
先不考慮建邊,先考慮已經有的邊,這些已經有的邊,本著能不刪就不刪的原則 ( 這是顯然的,因為刪去的話可能需要重新建一條邊 ) ,從大到小列舉已經有的邊,能加入並查集合並的就合併,如果當前邊連線的兩個點已經在同乙個集合當中,這個時候,因為樹的結構的限制,一定需要刪除這條邊,而且我們是從大到小列舉的,所以刪除邊的代價是最小的。
至此,我們能留下的原有的邊是最多的,現在需要做的就是補充完樹的結構,對於可以建的邊做一遍最小生成樹即可。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define x first
#define y second
#define l (u<<1)
#define r (u<<1|1)
#define mid (tr[u].l+tr[u].r>>1)
#define len(u) (tr[u].r-tr[u].l+1)
using
namespace std;
typedef
long
long ll;
typedef pair<
int,
int> pii;
const
int n=
1010
,mod=
1e9+
7,inf=
0x3f3f3f3f
;const
double eps=
1e-6
;int n;
int p[n*n*2]
;int g[n]
[n];
struct node
}edge1[n*n*2]
,edge2[n*n*2]
;void
init
(int n)
intfind
(int x)
intmain()
;else edge2[
++cnt]=;
}init
(max
(tot,cnt));
sort
(edge2+
1,edge2+
1+cnt)
;for
(int i=cnt;i>=
1;i--
)sort
(edge1+
1,edge1+
1+tot)
;for
(int i=
1;i<=tot;i++)}
cout
}
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...
最小生成樹
package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...
最小生成樹
define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...