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