最大生成樹

2021-08-09 18:32:20 字數 2771 閱讀 3618

problem a: 古老的羊皮卷

time limit: 3 sec  memory limit: 128 mb

description

奇奇,乙個響亮的名字在acm界.如今奇奇已經腰纏萬貫,飛黃騰達,日子過的是無比的滋潤.是什麼使他到了如此的地位?如果你要這麼問,奇奇會不假思索的告訴你:"acm! 是acm讓他思維敏捷而縝密,是acm讓他頭腦靈活而聰慧,是acm讓他謀事果斷而細心......".但每天安逸的生活使得奇奇很是煩悶,由於他小時候夢想著找寶藏,於是奇奇打算去歷(zuo)險(si).這不,瞎貓碰上死耗子,還真讓他不知從哪得來了一張古老的羊皮書.找個安靜隱秘的地方,奇奇開啟羊皮卷,內容甚是複雜,不過幸虧奇奇學過acm,利用早年所學的的圖論、計算幾何、數論加密等一系列方法終於把羊皮卷還原了,原來是一張古代藏寶圖.只見地圖上有 n 個可能藏有寶物的地方,這 n 個地方一共有 m 條路, 每條路的兩端連通著兩個地方,路兩兩互不相通,每兩個地方之間僅存在一條路,路是雙向可達的.每條路都有乙個凶險值,奇奇不知道具體的凶險值是多少,只知道路越長則凶險值越小,每條路的長度在藏寶圖中都有標明.奇奇想去一一探查這 n 個地方,為了使得總的凶險值越小,他想選擇盡量少的路能到達這 n 個地方,其次在路盡量少的情況下保證總的凶險值也盡量少,也即他所選擇的各個路的距離之和最大.這是乙個複雜的問題,奇奇已經力不從心了,於是只好求學弟學妹們幫他找到乙個方案滿足他的要求,如果你找到了,那麼他將會把他所得的藏寶分你一半,否則你就會被陷入絕望的奇奇"嘿嘿嘿".

input

輸入資料有多組,對於每組資料報含若干行.每組資料的第一行有兩個數字 n 和 m (0 < n <= 1000, 0 <= m < 1000,000),代表著有 n 個奇奇要去的地方(分別編號為1, 2, ..., n), 這 n 個地方存在 m 條路.緊接著 m 行,每行有三個數 i, j, k, 代表著第 i 號藏寶地到第 j 號藏寶地之間的路的距離為 k (0 < u, v <= n. 0 < w < 100,000), 輸入資料保證 n 個地方相互連通.

output

對於每組輸入,在單獨的一行輸出乙個數字,代表著滿足奇奇要求的路線中每條路的距離之和.

sample input

4 51 2 9

4 2 7

3 1 6

3 2 3

4 3 5

sample output

hint

奇奇要去 4 個地方, 這 4 個地方由 5 條路連通, 選擇 1 --> 2, 1 --> 3, 2 --> 4 這三條路將使得總路線最長為 22.

#include

#include

#include

#include

using namespace std;

#define inf 99999999

int n,m;

int mp[1008][1008];

int used[1008],low[1000008];

int prime(int n)

int sum=0,i,time=1,k;

memset(used,0,sizeof(used));//清零

used[1]=1;//選取第乙個點

for(i=2;i<=n;i++)

low[i]=mp[1][i];//與第乙個點相連的線段的權值存在陣列中

//printf("%d\n",low[i]);

while(time<=n-1)//因為每迴圈一次找出乙個點,所以只要迴圈

n-1次一定能夠把最小生成樹找出來

int it=-1;//先將最小值設成乙個大數

int j=0;

for(k=2;k<=n;k++)

//printf("low[k]=%d\n",low[k]);

if(low[k]>it&&used[k]==0)//找兩個點之間的最短距離且另乙個點沒用過

it=low[k];//更新最小值

j=k;

//printf("it=%d\n",it);

sum=sum+it;//加上最小值

used[j]=1;//這個點用過標記為1

//printf("j=%d\n",j);

for(k=2;k<=n;k++)

if(mp[j][k]>low[k]&&used[k]==0)//找這個點與其他點之間的最短距離且另乙個點也沒用過

low[k]=mp[j][k];//更新最小值

//printf("low[k]=%d\n",low[k]);

time++;

return sum;

int main()

while(cin>>n>>m)

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

mp[i][j]=-99999;

for(int i=1;i<=m;i++)

int x,y,val;

cin>>x>>y>>val;

mp[x][y]=val;

mp[y][x]=val;

/*for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

printf("%d ",mp[i][j]);

printf("\n");

cout注意:備註差不多是反著的

由之前最小生成樹的模板改的

。。。這個是不容易超時的。。。

最大生成樹

include define pp make pair using namespace std typedef long long ll const int maxn 1e6 30 const int n 260000 const ll mod 1e9 7 const int inf 0x3f3f3...

最大生成樹

最大生成樹演算法和最小生成樹演算法幾乎一樣,只需要我們把最小生成樹演算法進行一點點改變即可。當你用krushal演算法求最小生成樹的時候,每一次選取的邊都是最小的邊,然後再去判斷這條邊是否可以加入最小生成樹 那麼當你每一次選擇的邊是最大的邊,然後再去判斷這條邊是否可以加入,那麼這就是最大生成樹的求取...

matlab prime最大生成樹

最近寫了個最大生成樹,根據兩個節點之間的互資訊作為邊的權重來進行編寫。希望能夠有所幫助 思路是先放到set中乙個點,然後找到所有與set相連的邊,按照降序排列,依次選擇判斷是否滿足prime的條件 function maxtree h importdata h.mat mutualinfo impo...