您的位置:首页 > 产品设计 > UI/UE

poj 1679 The Unique MST(图论:最小生成树)

2014-07-22 22:46 423 查看
题目是给定一个图,判断该图中的最小生成树是否唯一

若唯一输出生成树的权,否则输出Not Unique!

那么先要解决的一个问题是什么样的图对应不止一个最小生成树?

我们从prim算法来着手解决这个问题

加入当前最小生成树集合中已并入3个点,对于下一个即将要加入的点

如果最小生成树集合中存在一个以上的点到这个即将加入的点距离相等且为最小

则可以断定可构成不止一个最小生成树!

因为对于当前即将加入的点它有多个连接方法,当然对应多颗最小生成树

这样的话我们只用在prim的基础上稍微处理下就可以了

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 110
#define LL long long
#define INF 0x7fffffff
using namespace std;

int m, n, ans, min_edge, now_index;
int dis[MAXN], g[MAXN][MAXN];

bool prim() {
int now, minedge, minnode, i, j, cnt;
for(i=1; i<=n; ++i)
dis[i] = INF;
now = now_index;//从所有边中长度最短的对应端点开始,否则会漏掉
//    cout << "now = " << now << endl;
ans = 0;
for(i=0; i<n-1; ++i) {
dis[now] = -1;
minedge = INF;
for(j=1; j<=n; ++j) {
if(now!=j && dis[j]>=0) {
if(g[now][j] >= 0)
dis[j] = min(dis[j], g[now][j]);
if(minedge > dis[j]) {
minnode = j;
minedge = dis[j];
}
}
}
//        cout << "minedge = " << minedge << endl;
cnt = 0;
for(j=1; j<=n; ++j) {
//            cout << "dis[" << j << "] = " << dis[j] << endl;
if(dis[j]<0 && g[minnode][j]==minedge)//在已并入最小生成树点集中找到距离当前点长度最小的点的个数
cnt++;
}
//        cout << "cnt = " << cnt << endl;
if(cnt > 1)
return false;

ans += minedge;
now = minnode;
}
return true;
}

int main(void) {
int T, x, y, len;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
memset(g, -1, sizeof(g));
min_edge = INF;
now_index = 1;
while(m--) {
scanf("%d%d%d", &x, &y, &len);
g[x][y] = g[y][x] = len;
if(min_edge > len) {//找到所有边中长度最小的边对应的一个端点
min_edge = len;
now_index = y;
}
}
if(prim())
cout << ans << endl;
else cout << "Not Unique!" << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: