行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;
/*#define inf 0x3f3f3f3f
int edge[500][500],lowcost[500],v[500],n,m;
void prim()
{
int next,minn,i,sum,flag;
memset(v,0,sizeof(v));
v[1]=1;
sum=0;
flag=0;
for(int i=1;i<=m;i++)
lowcost[i]=edge[1][i];
for(i=2;i<=m;i++)
{
minn=inf;
for(int j=1;j<=m;j++)
{
if(!v[j]&&minn>lowcost[j])
{
minn=lowcost[j];
next=j;
}
}
if(minn==inf)
{
//cout<<"?"<<endl;
//printf("?\n");
//return ;//
flag=1;break;
}
sum+=minn;
v[next]=1;
for(int j=1;j<=m;j++)
{
if(!v[j]&&lowcost[j]>edge[next][j])
lowcost[j]=edge[next][j];
}
}
//printf("%d\n",sum);
//cout<<sum<<endl;
if(flag) printf("?\n");//cout<<"?"<<endl;
else printf("%d\n",sum);//cout<<sum<<endl;
for(i=1;i<=m;i++)
{
if(!v[i]) { cout<<"?"<<endl;break;}
}
if(i>m) cout<<sum<<endl;
//}
/*int main()
{
int i,j,a,b,c;
while(cin>>n>>m)
{
if(n==0) break;
/*if(n<m-1)
{
cout<<"?"<<endl;
continue;
}
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)
{
//if(i==j)
// edge[i][j]=0;
//else
edge[i][j]=inf;
}
}
for(i=1;i<=n;i++)
{
//cin>>a>>b>>c;
scanf("%d%d%d",&a,&b,&c);
edge[a][b]=edge[b][a]=c;
}
prim();
}
}*/prim
struct node
{
int s,e,v;
};
node edge[200];
int fat[110];
bool cmp(node a,node b)
{
return a.v<b.v;
}
int find(int x)
{
if(x!=fat[x]) fat[x]=find(fat[x]);
return fat[x];
}
void unionn(int x,int y)
{
int fa=find(x);
int fb=find(y);
if(fa!=fb) fat[fa]=fb;
}
int main()
{
int n,m,i,a,b,c,tot,k;
while(cin>>n>>m)
{
if(n==0)
break;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&c);
edge[i].s=a;
edge[i].e=b;
edge[i].v=c;
}
tot=0;k=0;
for(i=1;i<=m;i++) fat[i]=i;
sort(edge+1,edge+1+n,cmp);
for(i=1;i<=n;i++)
{
if(find(edge[i].s)!=find(edge[i].e))
{
unionn(edge[i].s,edge[i].e);
tot+=edge[i].v;
k++;
}
}
if(k==m-1) cout<<tot<<endl;
else cout<<"?"<<endl;
}
}
需要判断有没有生成书