pta题解
习题8.4 畅通工程之最低成本建设问题 (30分)
这题是最小生成树问题,先将费用进行排序,每一次都选取当前最小的费用的那条路,然后用并查集,看看有没有成环,如果没有就将相连的道路进行标记,最后统计是否所有的城镇都连起来了,如果只要一个城镇的主人是自己,那就符合要求。
#include<stdio.h>
int f[10000];
struct way
{
int a;
int b;
int cost;
};
int getf(int v)
{
if(f[v]==v)
return v;
else
{
int tmp = getf(f[v]);
f[v] = tmp;
return tmp;
}
}
struct way q[10000];
int main()
{
struct way t;
int n,m;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(n==0)
break;
int i,sum=0,j;
int num=0;
for(i=0;i<=m;i++)
{
f[i]=i;
}
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].cost);
}
for(i=1;i<=n-1;i++)
{
for(j=1;j<=n-i-1;j++)
{
if(q[j].cost>q[j+1].cost)
{
t=q[j];
q[j]=q[j+1];
q[j+1]=t;
}
}
}
int x,y;
for(i=1;i<=n;i++)
{
x=getf(q[i].a);
y=getf(q[i].b);
if(x!=y)
{
f[x]=y;
sum+=q[i].cost;
}
}
for(i=1;i<=m;i++)
{
if(f[i]==i)
num++;
}
if(num==1)
printf("%d\n",sum);
if(num>1)
printf("Impossible\n");
}
}
习题8.5 畅通工程之局部最小花费问题 (35分)
这题和上面这题很像,但是这题要考虑已经修好的路,一开始在输入的时候,我们就将已经修好的路进行标记,然后将还没修好路费用进行排序,然后跟刚刚一样,选取一条路,先判断有没有成环了,没有就进行标记,然后算进总费用。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct way
{
int a;
int b;
int cost;
int t;
};
int f[50000];
int getf(int v)
{
if(v==f[v])
return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}
void mer(int x,int y)
{
int f1=getf(x);
int f2=getf(y);
if(f1!=f2)
{
f[f1]=f2;
}
}
int cmp(way a,way b)
{
return a.cost<b.cost;
}
int main()
{
struct way q[50000];
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
int i;
for(i=0;i<=n;i++)
{
f[i]=i;
}
int k=n*(n-1)/2;
int j=0;
int x1,x2,x3,x4;
for(i=0;i<k;i++)
{
scanf("%d%d%d%d",&x1,&x2,&x3,&x4);
{
if(x4==1)
{
mer(x1,x2);
}
else
{
q[j].a=x1;
q[j].b=x2;
q[j].cost=x3;
j++;
}
}
}
sort(q,q+j,cmp);
int flag=0,sum=0;
for(i=0;i<j;i++)
{
if(getf(q[i].a)!=getf(q[i].b))
{
f[getf(q[i].a)]=f[getf(q[i].b)];
sum=sum+q[i].cost;
}
}
printf("%d\n",sum);
}
}