题意:给一个图,问其最小生成树是否惟一。
思路:用Kruskal 算出最小生成树的值,并记录每一条边,然后枚举去掉这些边 看其是否也能构成最小生成树且值相同。注意 在删边后,可能图构不成一棵树,得判断一下
//264K
16MS
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define M 10010
#define N 105
using namespace std;
struct E
{
int u,v,w;
} edge[M];
int n,m,mst;
int parent[N];
bool flag;
bool cmp (E a,E b)
{
return a.w < b.w;
}
void Init ()
//并查集数组初始化
{
for (int i = 0; i < N; i ++)
parent[i] = i;
}
int find (int x) //查找是否属同一集合
{
if (x != parent[x])
parent[x] = find(parent[x]);
return parent[x];
}
void Kruskal ()
{
int i,j,u,v;
int path[M];
mst = 0;
i = 0,j = 0;
flag = true;
Init();
while (j < n-1&&i < m)
{
u = find (edge[i].u);
v = find (edge[i].v);
if (u != v)
//不在同一集合
{
parent[v] = u;
mst += edge[i].w;
path[j++] = i;
//记录路径
}
i ++;
}
for (int k = 0; k < n-1; k ++)
//枚举去掉每一条边
{
int sum = 0;
j = 0,i = 0;
Init();
while (j < n - 1&&i < m)
{
if (i == path[k])
{
i ++;
continue;
}
u = find (edge[i].u);
v = find (edge[i].v);
if (u != v)
{
parent[v] = u;
sum += edge[i].w;
j ++;
}
i ++;
}
if
(j != n - 1)
//判断是否能构成树 WA了一次
continue;
if (mst == sum)
{
flag = false;
return ;
}
}
}
int main ()
{
int T,i;
scanf ("%d",&T);
while (T --)
{
scanf ("%d%d",&n,&m);
for (i = 0; i < m; i ++)
scanf ("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
sort (edge,edge + m,cmp);
Kruskal ();
if (!flag)
printf ("Not Unique!\n");
else
printf ("%d\n",mst);
}
return 0;
}
思路:用Kruskal 算出最小生成树的值,并记录每一条边,然后枚举去掉这些边 看其是否也能构成最小生成树且值相同。注意 在删边后,可能图构不成一棵树,得判断一下
//264K
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define M 10010
#define N 105
using namespace std;
struct E
{
} edge[M];
int n,m,mst;
int parent[N];
bool flag;
bool cmp (E a,E b)
{
}
void Init ()
{
}
int find (int x) //查找是否属同一集合
{
}
void Kruskal ()
{
}
int main ()
{
}