http://acm.hdu.edu.cn/showproblem.php?pid=1863
还是最小生成树,还是用了kruskal写,就是有点不一样的地方在于,他要让你判断是否能够保证畅通,也就是是否能有最小生成树,其实就是判断是不是连通图吧,因为连通图一定会有最小生成树。
一开始我的想法是,先进行一次并查集的合并与查找,看一下有几个集合,如果只有一个集合的话就是连通图,肯定有最小生成树存在,如果多余一个集合就不会有,直接输出问好。之后要记得还原根节点。。
附上代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000000
int u[M],v[M],p[M],w[M];
int r[M],t[M];
int n,m;
int ans;
int cmp(int a,int b)
{
return w[a] < w[b];
}
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
void uni(int x,int y)
{
if(x!=y)
p[x] = y;
}
int kruskal()
{
for(int i = 0;i < n;i++)
{
int e = r[i];
int x = find(u[e]),y = find(v[e]);
if(x!=y)
{
p[x] = y;
ans += w[e];
}
}
}
int main()
{
while(scanf("%d %d",&n,&m)==2 && n)
{
memset(t,0,sizeof(t));
ans = 0;
int num = 0;
for(int i = 1;i <= m;i++) p[i] = i;
for(int i = 0;i < n;i++) r[i] = i;
for(int i = 0;i < n;i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
uni(u[i],v[i]);
}
for(int i = 1;i <=m;i++)
{
int temp = find(i);
if(t[temp]==0)
{
num++;
t[temp]++;
}
}
if(num!=1)
{
printf("?\n");
continue;
}
for(int i = 1;i <= m;i++)
p[i] = i;
sort(r,r+n,cmp);
kruskal();
printf("%d\n",ans);
}
return 0;
}
因为最小生成树的边一定是n-1条边,那么其实我们还可以计算一下边数,在将找到的边加入最小生成树的时候顺便做就行了,那么如果这个边数小于n-1的话,肯定就不是连通图没有最小生成树。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000000
int u[M],v[M],p[M],w[M];
int r[M],t[M];
int n,m;
int ans;
int cmp(int a,int b)
{
return w[a] < w[b];
}
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
bool kruskal()
{
int sum = 0;
for(int i = 0;i < n;i++)
{
int e = r[i];
int x = find(u[e]),y = find(v[e]);
if(x!=y)
{
p[x] = y;
ans += w[e];
sum++;
}
}
if(sum < m-1)
return false;
return true;
}
int main()
{
while(scanf("%d %d",&n,&m)==2 && n)
{
memset(t,0,sizeof(t));
ans = 0;
int num = 0;
for(int i = 1;i <= m;i++) p[i] = i;
for(int i = 0;i < n;i++) r[i] = i;
for(int i = 0;i < n;i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
}
sort(r,r+n,cmp);
bool ok = kruskal();
if(ok)
printf("%d\n",ans);
else
printf("?\n");
}
return 0;
}