Constructing RoadsTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 28201 Accepted Submission(s): 10744 http://acm.hdu.edu.cn/showproblem.php?pid=1102 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 |
题意:
1到N个村庄,已知一些村庄之间已经有一些道路。要求修建一些道路,使所有村庄都连通起来,使所有道路长度最小。
思路:
最小生成树问题(Prim算法)。 把之前就有道路的村庄看成一个点,即mapp[i][j]=mapp[j][i]=0。
代码:
#include<iostream>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int vis[105];
int mapp[105][105];
int l[105][105];
int dis[105];
int n;
int prim(int s)
{
long long sum=0;
vis[s]=0;
for(int i=1;i<=n;i++)
dis[i]=i==s?0:mapp[i][s];
int minn;
int k;
for(int i=1;i<=n;i++)
{
minn=inf;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&minn>dis[j])
{
minn=dis[j];
k=j;
}
}
vis[k]=1;
sum+=minn;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]>mapp[k][j])
dis[j]=mapp[k][j];
}
}
return sum;
}
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cin>>mapp[i][j];
}
int q;
cin>>q;
int a,b;
memset(vis,0,sizeof(vis));
while(q--)
{
cin>>a>>b;;
mapp[a][b]=mapp[b][a]=0;
}
long long sum=prim(1);
cout<<sum<<endl;
}
return 0;
}