您的位置:首页 > 其它

poj1679----最小生成树

2012-08-15 10:31 169 查看
题目大意:

判断是否存在最小生成树。

如果存在,判断其是否唯一。

用prim算法求最小生成树。

将其中的每一条边依次替换,权值是否和最小生成树相同。

如果相同,则最小生成树不唯一。

如果都不相同,则唯一。

第一次做最小生成树,不会写,参考的别人的代码:

这个prim的模板比较好,可以再求最小生成树的同时直接进行判断唯一性。

代码如下:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
#define MAX 250
#define INF 1000000

int dis[MAX][MAX];
int t, n, m;
int result;
struct node
{
int v1;
int v2;
int len;
}e[MAX];

void init()
{
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{    dis[i][j] = INF;
//printf("dis[%d][%d]=%d\n", i, j, dis[i][j]);
}
}
int prim()
{
int result=0;
int i, j, min, minL, vx, vy, leng;
for(i=0; i<n-1; i++)
{
e[i].v1=0;
e[i].v2=i+1;
e[i].len=dis[0][i+1];
//printf("e[%d].len=%d\n", i, dis[0][i+1]);
}
for(i=0; i<n-1; i++)
{
minL=INF;
min=-1;
for(j=i; j<n-1; j++)
{
if(e[j].len < minL)
{
minL=e[j].len;
min=j;
}
}
if(min==-1)
break;
swap(e[min],e[i]);
result += minL;
for(j=0; j<i; j++)//在prim模板的基础上加上这个循环判断mst是否唯一
{
if(dis[e[j].v2][e[i].v2]==minL && e[j].v2!=e[i].v1)
return -1;
}
vx=e[i].v2;
for(j=i+1; j<n-1; j++)
{
vy=e[j].v2;
leng=dis[vx][vy];
if(leng < e[j].len)
{
e[j].len=leng;
e[j].v1=vx;
}
}
}
return result;
}
int main()
{
while(scanf("%d", &t)!=EOF)
{
int x, y, z;
for(int i=0; i<t;i++)
{
scanf("%d%d", &n, &m);
init();
for(int j=0; j<m; j++)
{
scanf("%d%d%d", &x, &y, &z);
x--;
y--;
dis[x][y] = dis[y][x] = z;
}
/*for(x=0; x<n; x++)
{    for(y=0; y<n; y++)
printf("%7d ", dis[x][y]);
printf("\n");
}*/
result=prim();
if(result < 0)
printf("Not Unique!\n");
else printf("%d\n", result);
}
}
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: