poj1679
分析:本題可以通過求出次小生成樹,然後再比較次小生成樹與最小生成是否相等來判斷最小生成樹是否唯一。
我們仔細回想一下kruskal求最小生成樹的過程,最後得到的一定是乙個無向連通圖,如果我們要想求次小生成樹的話,我們可以考慮列舉每一條不屬於最小生成樹的邊,然後這條邊會和原先的最小生成樹的一些邊構成乙個環,在這個環內,我們需要找出一條最大的邊:maxd[i][j] 來和那條邊進行比較(沒在最小生成樹的的那條邊:es[i]),此時我們要定義乙個變數:pre=inf,假設變數sum是最小生成樹的權值總和,那麼通過pre=min(pre,sum+es[i].w-maxd[es[i].s][es[i].e])來更新pre的值,最後pre的值就是次小生成樹的值。對於上述maxd[i][j]意思是:在最小生成樹里從i到j的邊中最大的邊的權值,我們可以利用動態規劃的思想來做:當集合要合併的時候我們就可以: maxd[g[px][j]][g[py][k]]=maxd[g[py][k]][g[px][j]]=es[i].w;
參考下面**:
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int maxn=
110;
const
int inf=
0x3f3f3f3f
;struct nodees[maxn*maxn]
;int p[maxn]
;vector<
int> g[maxn]
;int maxd[maxn]
[maxn]
;int n,m,sum;
bool
cmp(node x,node y)
intfinds
(int x)
void
kruskal()
int sum=
0,k=0;
for(
int i=
0;i//if(k==n-1)break;
p[px]
=py;
for(
int j=
0;j.size()
;j++)}
}int pre=inf;
for(
int i=
0;i//printf("%d %d\n",sum,pre);
if(pre<=sum)
else
}int
main()
kruskal()
;}return0;
}
POJ 1679 次小生成樹
判斷最小生成樹是否唯一,方法是這樣的 1.對圖中每個點,掃瞄其他的邊,如果存在其他權值相同的邊,則對改邊作標記 2.然後用 kruskal或者prim 求mst 3.求的mst後,如果該mst不包含作了標記的邊,即可判定mst唯一 如果包含作了標記的邊,則依次去掉這些邊在求mst,如果求的mst權值...
poj 1679(次小生成樹)
題意 給你乙個圖,求最小生成樹是否唯一。思路 求次小生成樹,看它和最小生成樹的權值是否相等。include include include include define inf 99999999 using namespace std int vis 10005 int f 105 int n,m ...
POJ 1679 次小生成樹
題目大意,t組樣例輸入,n個點m條邊,求除最小生成樹以外的最短邊。暴力,可勁暴力,資料水,暴力出奇蹟 模擬不選每條最小生成樹中的邊,取最小 by acer.mo include include include include include include includeusing namespac...