poj 1679 The Unique MST

判断MST是否唯一,用次小生成树的方法,如果次小生成树和原来的最小的相等,就不唯一。

数据看来保证是连通的了。。

N^3的算法。。。如果把树存成链表,就是N^2算法了。悲剧的北京A题。。

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 110;

int a[MAX][MAX];
int medge[MAX][MAX];
bool in[MAX][MAX];
int dis[MAX][MAX];

int Prim( int n )  
{  
    int used[MAX],dis[MAX],i,j,sum = 0,now,min;  
	pair<int,int> pii[MAX];    
    memset(used,0,sizeof(used));
    fill(dis,dis+MAX,INT_MAX);
    
    now = 0; dis[now] = 0; used[now] = 1;  
    for(i=1; i<n; i++)  
    {  
        for(j=0; j<n; j++)  
            if( !used[j] && dis[j] > a[now][j] ) 
			{
				pii[j] = make_pair(now, j);
                dis[j] = a[now][j];
			}  
        min = INT_MAX;  
        for(j=0; j<n; j++)  
            if( !used[j] && dis[j] < min )  
                min = dis[now = j];  
        used[now] = 1;  
        sum += min;  
        
        in[pii[now].first][pii[now].second] = in[pii[now].second][pii[now].first] = true;
    }  
    return sum; 
}

void BFS(int x, int n)
{
	bool used[MAX];
	memset(used, 0, sizeof(used));
	queue<int> q;
	q.push(x);
	used[x] = true;
	while( !q.empty() )
	{
		int now = q.front(); q.pop();
		FOR(i, 0, n)
			if( in[now][i] && !used[i] )
			{
				used[i] = true;
				q.push(i);
				dis[x][i] = max(a[now][i], dis[x][now]);
			}
	}	

}
int solve( int n )
{
	memset(in, false, sizeof(in));
	int sum = Prim(n);
	
	FOR(i, 0, n)
		BFS(i, n);

	FOR(i, 0, n)
		FOR(k, i+1, n)
			if( !in[i][k] && a[i][k] == dis[i][k] )
				return -1;
	return sum;
}
int main()
{
	int ncases, n, m, u, v, w;
	
	scanf("%d", &ncases);
	
	while( ncases-- )
	{
		scanf("%d%d", &n, &m);
		
		FOR(i, 0, n)
			FOR(k, 0, n)
				a[i][k] = INT_MAX;
		while( m-- )
		{
			scanf("%d%d%d", &u, &v, &w);
			u--; v--;
			a[u][v] = a[v][u] = w;
		}
		
		int ans = solve( n );
		
		if( ans == -1 )
			printf("Not Unique!\n");
		else
			printf("%d\n", ans);
	}
	
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值