您的位置:首页 > 其它

HDU-1863-畅通工程(最小生成树)

2018-02-04 16:23 253 查看

                                             畅通工程

                                     


                                                      Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

                                                                   Total Submission(s): 34156    Accepted Submission(s): 15127


[align=left]Problem Description[/align]
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。

 

[align=left]Input[/align]
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N

行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。

 

[align=left]Output[/align]
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。

 

[align=left]Sample Input[/align]


3 31 2 11 3 22 3 41 32 3 20 100

 
[align=left]Sample Output[/align]


3?

普里姆算法

#include<iostream>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
int G[105][105],vis[105],cost[105];
int m,n,flag;
int dfs(int u)
{
vis[u]=1;
for(int v=1;v<=n;v++)
if(!vis[v]&&G[u][v]!=inf)
dfs(v);
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(vis,0,sizeof(vis));
memset(cost,0,sizeof(cost));
memset(G,inf,sizeof(G));
if(m==0) return 0;
int a,b,w,ans=0;
flag=0;
for(int i=1;i<=m;i++)
{
cin>>a>>b>>w;
G[a][b]=G[b][a]=w;
}
dfs(1);
for(int i=1;i<=n;i++)
if(!vis[i])
{flag=1;break;}
if(flag)
{ cout<<"?"<<endl; continue; }
for(int i=2;i<=n;i++)
cost[i]=G[1][i];
for(int i=1;i<n;i++)
{
int k=1;
for(int j=1;j<=n;j++)
if(cost[j]) {k=j; break; }
int mincost=cost[k];
for(int j=1;j<=n;j++)
if(cost[j]&&cost[j]<mincost)
{ mincost=cost[j];k=j;}
ans+=cost[k];
cost[k]=0;
for(int j=1;j<=n;j++)
if(cost[j]>G[k][j])
cost[j]=G[k][j];

}cout<<ans<<endl;
}
}


克鲁斯卡尔算法

#include<iostream>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
struct Node
{
int u,v,w;
}edge[105];
int vset[105],f[105],n,m;
bool cmp(Node a,Node b)
{return a.w<b.w;}
int find(int x)
{
if(f[x]!=x)
f[x]=find(f[x]);
return f[x];
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
if(m==0) return 0;
for(int i=1;i<=n;i++)
{vset[i]=i;f[i]=i;}
int a,b,w,flag=0;
for(int i=1;i<=m;i++)
{
cin>>a>>b>>w;
edge[i].u=a,edge[i].v=b,edge[i].w=w;
int a1=find(a),b1=find(b);
if(a1!=b1) f[a1]=b1;
}
int F=find(1);
for(int i=2;i<=n;i++)
if(find(i)!=F)
{ flag=1;break;}
if(flag) {cout<<"?"<<endl;continue;}
sort(edge+1,edge+m,cmp);
int m1,m2,sn1,sn2,cnt=1,ans=0;
for(int i=1;i<=m;i++)
{
m1=edge[i].u,m2=edge[i].v;
sn1=vset[m1],sn2=vset[m2];
if(sn1!=sn2)
{
ans+=edge[i].w;
cnt++;	if(cnt==n)break;
for(int j=1;j<=m;j++)
if(vset[j]==sn1)
vset[j]=sn2;
}
}
cout<<ans<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: