NYOJ 118 修路方案

2021-07-25 04:30:30 字數 1777 閱讀 6634

時間限制:

3000 ms  |  記憶體限制:

65535 kb

難度:5 描述

南將軍率領著許多部隊,它們分別駐紮在n個不同的城市裡,這些城市分別編號1~n,由於交通不太便利,南將軍準備修路。

現在已經知道哪些城市之間可以修路,如果修路,花費是多少。

現在,軍師小工已經找到了一種修路的方案,能夠使各個城市都聯通起來,而且花費最少。

但是,南將軍說,這個修路方案所拼成的圖案很不吉利,想讓小工計算一下是否存在另外一種方案花費和剛才的方案一樣,現在你來幫小工寫乙個程式算一下吧。

輸入

第一行輸入乙個整數t(1

輸出對於每組測試資料輸出yes或no(如果存在兩種以上的最小花費方案則輸出yes,如果最小花費的方案只有一種,則輸出no)

樣例輸入

2

3 31 2 1

2 3 2

3 1 3

4 41 2 2

2 3 2

3 4 2

4 1 2

樣例輸出

no

yes

首先,用kruskal求得最小生成樹,並用visit陣列記錄最小生成樹的邊,假設為總共num條

然後,迴圈求最小生成樹num次,每次都不用第一次求得的最小生成樹的邊

假設:第一次求最小生成樹用到了 1、2、4這三條邊,總共5條邊,那迴圈3次的時候,每次分別不用1、2、4求得最小生成樹的mst,最小的mst即為次小生成樹

ac**:不加剪枝險些超時,2600ms,加剪枝會大大優化,縮短到150ms

#include #include #include #include #define max 500 + 10

#define inf 0x3fffffff

using namespace std;

typedef struct edge;

vectoredge;

int father[max];

int visit[max];

int mst;

int secmst;

int numedge;

void initset()

}int findfather( int x )

while( a != father[a] )

return x;

}void union( int a, int b )

int cmp( edge a, edge b )

void kruskal( int n )

}//if( cnt == n - 1 )

//printf( "%d %d\n", numedge, mst );

}void secmintree( int n ) }}

// 每次求得乙個生成樹,更新次小生成樹的權值

if( cnt == n - 1 && curmintree < secmst )

// 剪枝,如果當前所求的次小生成樹已經和最小生成樹權值相同,return

if( secmst == mst ) return;

}}int main()

kruskal( n ); // 求最小生成樹

secmintree( n ); // 求次小生成樹

//printf( "%d %d\n", mst, secmst );

if( mst == secmst )

else

}return 0;

}

NYOJ 118 修路方案

時間限制 3000 ms 記憶體限制 65535 kb 難度 5描述 南將軍率領著許多部隊,它們分別駐紮在n個不同的城市裡,這些城市分別編號1 n,由於交通不太便利,南將軍準備修路。現在已經知道哪些城市之間可以修路,如果修路,花費是多少。現在,軍師小工已經找到了一種修路的方案,能夠使各個城市都聯通起...

nyoj 118 修路方案

時間限制 3000 ms 記憶體限制 65535 kb 難度 5 描述 南將軍率領著許多部隊,它們分別駐紮在n個不同的城市裡,這些城市分別編號1 n,由於交通不太便利,南將軍準備修路。現在已經知道哪些城市之間可以修路,如果修路,花費是多少。現在,軍師小工已經找到了一種修路的方案,能夠使各個城市都聯通...

nyoj118 修路方案 次小生成樹

如果已知最小生成樹,將未在生成樹的一條路徑加入生成樹必會產生乙個環,刪除環中除剛新增的一條以外的最大邊剩下的就是次小生成樹.求最小生成樹時用maxd陣列儲存兩點間最大的一條邊刪除時使用.include define inf 0x3f3f3f3f using namespace std const i...