题意:求村庄联通需要几条路
思路:就是老师上课讲的求最小生成树的算法,有两个,一个prim,一个kruskal。
感想:在acm与运筹学,离散数学,高等数学结合以后,又一次抱上了数据结构的大腿。
#include<iostream>
#include<algorithm>using namespace std;
struct node{
int from;
int to;
int w;
};
node edge[102*100];
int parent[102];
bool cmp(node a,node b)
{
if(a.w<=b.w) return true;
return false;
}
//查找已经建完道路的顶点
int find(int a)
{
if(a!=parent[a])
return find(parent[a]);
else return a;
}
int kruskal(int n,int m)
{
sort(edge,edge+m,cmp);//将边的权值从小到大排序
int i,x,y,ans=0;
for(i=0;i<m;i++)
{
x=edge[i].from;
y=edge[i].to;
x=find(x);
y=find(y);
if(x!=y)
{
ans+=edge[i].w;
parent[y]=x;
}
}
return ans;
}
int main()
{
int n,q,k,i,j,m;
while(cin>>n)
{
m=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>k;
if(i>=j) continue;//标记过的不用重复记录
edge[m].from=i;
edge[m].to=j;
edge[m].w=k;
m++;
}
}
for(k=1;k<=n;k++)
parent[k]=k;
cin>>q;
//将建完的道路的起点和终点都置为相同的起点
for(k=1;k<=q;k++)
{
cin>>i>>j;
i=find(i);
j=find(j);
parent[j]=i;
}
//n个点,m条边
cout<<kruskal(n,m)<<endl;
}
return 0;
}
3438

被折叠的 条评论
为什么被折叠?



