您的位置:首页 > 其它

poj 1679 最小 次小生成树

2013-01-10 16:33 169 查看
问题:判定最小支撑树的唯一性

网上有许多方法是求次小生成树,MST加并查集比较麻烦

prim算法中做一些调整

每一次寻找最小边的时候,判断最小边是否唯一

#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <queue>
using namespace std;

///宏定义
const int  INF = 1000000000;
const int MAXN = 110;
const int maxn = MAXN;
///全局变量 和 函数
#define CLR(a,num) memset(a,num,sizeof(a));

int n, m;
int graph[MAXN][MAXN];
int used[MAXN];
int dist[MAXN];
int prim()
{
int i, j;
int u, k;
int ans = 0, flag = 0;
CLR(used, 0);
//初始化dist数组为从结点1到各点的距离
for (i = 1; i <= n; ++i)
{
dist[i] = graph[1][i];
}
used[1] = 1;
for (i = 1; i < n; ++i)
{
int temp = INF;
//寻找当前结点出发的最短路径边
for (j = 1; j <= n; ++j)
{
if (!used[j] && dist[j] < temp)
{
temp = dist[j];
u = j;
}
}
//关键 查找当前的边是不是唯一
k = 0;
for (j = 1; j <= n; ++j)
{
if (used[j] && temp == graph[u][j])
{
++k;
}
}
used[u] = 1;
if (k > 1)
{
return -1;
}
ans += temp;
for (j = 1; j <= n; ++j)
{
if (!used[j] && graph[u][j] < dist[j])
{
dist[j] = graph[u][j];
}
}
}
return ans;
}
int main()
{
///变量定义
int i, j;
int cases;
scanf("%d", &cases);
while (cases--)
{
scanf("%d%d", &n, &m);
for (i = 1; i <= n; ++i)
{
for (j = 1; j <= n; ++j)
{
graph[i][j] = INF;
}
}
for (i = 1; i <= m; ++i)
{
int from, to, len;
scanf("%d%d%d", &from, &to, &len);
graph[from][to] = graph[to][from] = len;
}
int ans = prim();
if(ans == -1)
printf("Not Unique!\n");
else
printf("%d\n", ans);
}

///结束
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: