题意:给定一个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;
}