Constructing RoadsTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31205 Accepted Submission(s): 11782 Problem Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.
Input The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.
Output You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.
Sample Input 3 0 990 692 990 0 179 692 179 0 1 1 2
Sample Output 179 |
最小生成树 这里自己把边数和村庄数搞混了 首先是输入边 存矩阵的一半就可以 设置结构体来保存 然后输入已经连接的村庄的边 最后用kruskal 先排序边权 然后检查未连接的村庄 加入集合然后加上边权
kruskal:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int pre[101];
struct node
{
int x,y,w;
}edge[10001];
int cmp(node x,node y)
{
return x.w<y.w;
}
int find(int x)
{
if(pre[x]!=x)
return find(pre[x]);
else
return x;
}
int kruskal(int n,int num)
{
int ans=0;
sort(edge,edge+num,cmp);
for(int i=0;i<num;i++)
{
int p=edge[i].x,q=edge[i].y;
if(find(p)!=find(q))
{
ans+=edge[i].w;
pre[find(p)]=find(q);
}
}
return ans;
}
int main()
{
int t,n;
while(cin>>t)
{
memset(edge,0,sizeof(edge));
for(int i=1;i<=t;i++)
pre[i]=i;
int m,k=0;
for(int i=1;i<=t;i++)
for(int j=1;j<=t;j++)
{
cin>>m;
if(i<j)
{
edge[k].x=i;
edge[k].y=j;
edge[k].w=m;
k++;
}
}
cin>>n;
int a,b;
while(n--)
{
cin>>a>>b;
if(find(a)!=find(b))
pre[find(b)]=find(a);
}
cout<<kruskal(t,k)<<endl;
}
return 0;
}
prim:(先设置最短距离为无穷 用0x3f3f3f3f 选定1为起点 由1开始更新各个点到1的距离 记下最短距离 然后更新最短路径)
#include<iostream>
#include<cstring>
#define inf 0x3f3f3f3f
int n,m;
int map[101][101],dis[101],vis[101];
using namespace std;
int prim()
{
for(int i=1;i<=n;i++)
dis[i]=inf;
for(int j=1;j<=n;j++)
{
int t=inf,pos;
dis[1]=0;
for(int i=1;i<=n;i++)
{
//更新最短路径 并将其加入
if(!vis[i]&&t>dis[i])
{
t=dis[i];
pos=i;
}
}
vis[pos]=1;
for(int i=1;i<=n;i++)
{
//更新到pos点的最短距离 要未被访问且有边连接的点
if(!vis[i]&&map[pos][i]!=inf&&dis[i]>map[pos][i])
dis[i]=map[pos][i];
}
}
int ans=0;
for(int i=1;i<=n;i++)
ans+=dis[i];
return ans;
}
int main()
{
while(cin>>n)
{
memset(map,inf,sizeof(map));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>map[i][j];
}
cin>>m;
while(m--)
{
int a,b;
cin>>a>>b;
map[a][b]=0;
map[b][a]=0;
}
cout<<prim()<<endl;
}
return 0;
}