判断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;
}