1679 The Unique MST 次小生成樹
阿新 • • 發佈:2018-12-22
題意:給定一個n個頂點的圖,求問該圖的最小生成樹是否為唯一解,若是唯一解則輸出答案,不是則輸出“Not Unique!”。
思路:次小生成樹模板題,和最小生成樹的值比較一下就行了。
次小生成樹:先求出某個最小生成樹,然後跑一遍求該樹上任意兩個點的路徑上權值最大的邊maxedge[i,j],然後通過列舉圖上邊edge<i,j>,若不是樹上的邊,則用edge<i,j>替換maxedge[i,j]。這樣就求出一個比最小生成樹大的生成樹,其中最小的生成樹就是次小生成樹了。
#include<algorithm> #include<cmath> #include<cstring> #include<string> #include<map> #include<vector> #include<queue> #include<deque> #define ll long long #define PI acos(-1) #define INF 0x3f3f3f3f #define NUM 1000005 #define N 10005 #define debug true #define lowbit(x) ((-x)&x) #define ffor(i, d, u) for (int i = (d); i <= (u); ++i) #define _ffor(i, u, d) for (int i = (u); i >= (d); --i) #define mst(array, Num, Kind, Count) memset(array, Num, sizeof(Kind) * (Count)) using std::max; using std::queue; const int P = 1e9 + 7; int n, m; bool pick[NUM], root[105]; int maxedge[105][105]; struct node { int l, id; } ma[105][105]; struct node1 { int l, f; } dist[105]; template <typename T> void read(T& x) { x = 0; char c;T t = 1; while(((c=getchar())<'0'||c>'9')&&c!='-'); if(c=='-')t = -1,c = getchar(); do(x*=10)+=(c-'0');while ((c = getchar()) >= '0' && c <= '9'); x *= t; } template <typename T> void write(T x) { int len = 0;char c[21]; if(x<0)putchar('-'), x *= (-1); do{++len;c[len]=(x%10)+'0';}while (x /= 10); _ffor(i, len, 1) putchar(c[i]); } void bfs(const int &st)//求樹上點對路徑上邊的最小權值 { queue<int> q; int x; bool check[105] = {}; maxedge[st][st] = 0; x = st; check[st] = true; q.push(x); while(!q.empty()) { x = q.front(), q.pop(); ffor(i,1,n) { if(check[i]||ma[x][i].l==INF||!pick[ma[x][i].id>>1]) continue; maxedge[i][st] = maxedge[st][i] = max(maxedge[st][x], ma[x][i].l); check[i] = true; q.push(i); } } } void AC() { int t, x, y, pp, minx, ans; bool flag; read(t); dist[0].l = INF; while(t--) { read(n), read(m); mst(root, false, bool, n + 1), mst(pick, false, bool, m + 1); ffor(i, 1, n) ffor(j, 1, n) ma[i][j].l = ma[j][i].l = INF; ffor(i,1,m) { read(x), read(y); read(ma[x][y].l), ma[y][x].l = ma[x][y].l; ma[y][x].id = (ma[x][y].id = (i << 1) - 1) - 1; } flag = false,pp = 1,ans = 0,root[1] = true; ffor(i, 2, n) dist[i].l = ma[1][i].l, dist[i].f = 1; ffor(i,2,n)//prim { minx = 0; ffor(j,2,n) { if(root[j]) continue; if(dist[minx].l > dist[j].l) minx = j; } root[minx] = pick[ma[dist[minx].f][minx].id >> 1] = true, ans += dist[minx].l; ffor(j,2,n) { if(root[j]) continue; if(dist[j].l > ma[minx][j].l) { dist[j].l = ma[minx][j].l; dist[j].f = minx; } } } ffor(i, 1, n) bfs(i); ffor(i,1,n) { ffor(j,i+1,n) { if(pick[ma[i][j].id>>1]) continue; if(ma[i][j].l==maxedge[i][j]) { flag = true; break; } } if(flag) break; } if(flag) puts("Not Unique!"); else { write(ans); putchar('\n'); } } } int main() { AC(); return 0; }