HDU 1102-Constructing Roads

来源:互联网 发布:manbetx软件哪里下 编辑:程序博客网 时间:2024/05/18 00:04

Constructing Roads

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9149    Accepted Submission(s): 3383

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. 
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.
 
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.
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.
 
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

题意:
给你一个 n ,代表有 n 个村庄,编号从 1 到 n ,然后 n 行 n 列,数字的位置就是两点之间的距离,比如第二行第三个数代表村庄2到村庄3的距离,然后在给你一个 q,有 q 行,每行两个数 a 和 b ,代表村庄a到村庄b的路已经建好了,不需要你在计算了。


分析:
本题是最小生成树题,和单纯的找最短距离相比,本题多加一个点就是有的村庄之间的路已经建好了,不需要在建了。
有两种方法,第一种就是 Prim,存完路径后,将已经建好的村庄之间的路替换为 0(记住这里要双向标记为 0)
第二种方法就是 Kruskal,得用到并查集,将建好的路的村庄编号加到一个集合里面,我嫌它麻烦,选择了第一种。
在这里说一点很值得注意的事就是,prim 函数里我最初选的带你是 1,vis数组是用来标记该店是否用过,但vis【1】=1(代表1点已经用过)之后,下面的外层 for 循环就应该循环 n-1 次,如果 vis【1】为做标记,就循环 n 次,这个地方如果错了没注意的话,很难找出错误(我找了好久好久~),希望宝宝们多加注意^^




#include<iostream>#include<stdio.h>#include<string>#include<string.h>using namespace std;#define INF 0x3f3f3f3fint n,map1[105][105];void prim(){    int low[105],vis[105],bj,min1,sum;    memset(vis,0,sizeof(vis));    for(int i=1;i<=n;i++)    {        low[i]=map1[1][i];    }    ///vis[1]=1;    sum=0;    for(int i=1;i<=n;i++)//如果vis[1]=0的情况    ///for(int i=1;i<n;i++)    {        min1=INF;        for(int j=1;j<=n;j++)        {            if(!vis[j]&&min1>low[j])            {                bj=j;                min1=low[j];            }        }        sum+=min1;        vis[bj]=1;        for(int j=1;j<=n;j++)        {            if(!vis[j]&&low[j]>map1[bj][j])                low[j]=map1[bj][j];        }    }    printf("%d\n",sum);}int main(){    int a,b,q;    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                scanf("%d",&map1[i][j]);            }        }        scanf("%d",&q);        while(q--)        {            scanf("%d %d",&a,&b);            map1[a][b]=map1[b][a]=0;        }        prim();    }    return 0;}



原创粉丝点击