HDUOJ_1102(Constructing Roads)(最小生成树)

来源:互联网 发布:pickit3烧写软件 编辑:程序博客网 时间:2024/05/01 16:33

HDUOJ_1102(Constructing Roads)(最小生成树)

 Constructing Roads

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

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
30 990 692990 0 179692 179 011 2
 Sample Output
179

题意(输入输出):有n个村庄,n的下面有n组数据,0   990   692 表示第一个村庄到第一个村庄的距离为0,第二个村庄到第一个村庄的距离为990,第三个村庄到第一个村庄的距离为692,;   990  0   179表示第一个村庄到第二个村庄的距离为990,第二个村庄到第二个村庄的距离为0,第三个村庄到第二个村庄的距离为179.第i(1<=i<=n)行数据记录的是,所有村庄到第i个村庄的距离。

在n行数据下面有一个整数m,表示有m条公路已修建。m下面有m组数据,每组数据有两个整数表示已连通公路的两个村庄的编号。最后求连通全部村庄要修建公路的最短长度。

 

My  solution:

/*2015.8.13*/

#include<stdio.h>#include<algorithm>using namespace std;int per[110];int  temp[6000][2];   /*记录已修建公路的两个村庄的编号*/void chushihua(){int i;for(i=0;i<110;i++)per[i]=i;}struct stu{int a,b,s;}node[11000];int cmp(stu a,stu b){return a.s<b.s;}int find(int x){int i,j;i=x;while(i!=per[i])     i=per[i];     while(x!=per[x])     {     j=per[x];     per[x]=i;     x=j; } return i;}bool  join(int x,int y){ int fx,fy; fx=find(x); fy=find(y); if(fx!=fy)      {      per[fx]=fy;      return true;  }  else  return false;}int main(){int i,j,n,m,k,sum;while(scanf("%d",&n)==1){chushihua();   /*不要忘记调用*/k=-1;for(i=1;i<=n;i++){  for(j=1;j<=n;j++)  /*村庄编号从1开始*/{k++;   /*记录所有组合的总数*/node[k].a=i;    /*记录不同组合中的村庄编号和相应两个村庄之间的距离*/node[k].b=j;scanf("%d",&node[k].s);}}scanf("%d",&m);   /*记录已修建公路的数目*/for(i=0;i<m;i++)scanf("%d%d",&temp[i][0],&temp[i][1]);  /*temp数组记录已修建公路的两个村庄的编号*/sort(node,node+n*n,cmp);    /*node数组中共记录了n*n个数据*/k=0;sum=0;for(j=0;j<m;j++){if(join(temp[j][0],temp[j][1]))   /*优先连接已修建公路的村庄,因为当前需修建的公路长度为0*/  k++;  /*K用来记录当前已连接公路的数目*/ }/*注意:n个村庄之间有n-1条公路便可全部连通*/if(k<n-1)   /*若村庄之间都已连通,则不需要再修建道路*/{    for(j=n;j<n*n;j++)/*这里的j=n,是因为前n个数据都是0无效,因为这n个数据记录的是村庄自己到自己的距离,都为0。*/                   /*注意:该数组是从0号元素开始记录*/    if(k<n-1)  /*最初写的是for(j=n;j<n*n;j=j+2),因为(就用村庄1和村庄2举例:1到2和2到1的距离相等)*/             /*但记录时二者都记录了,在排序后,这两个数据因为相等必然相连,*/     {        /*此时用j=j+2很方便的只取其中的第一个数,跳过重复,直接取下一条数据,以此类推。*/           /*可是最后提交时总是荅案错误,于是改了过来就AC,可能这道题中1到2和2到1的距离不同吧*/       if(join(node[j].a,node[j].b))      {          k++; /*K用来记录当前已连接公路的数目*/           sum+=node[j].s;  /*记录需修建的道路总长度*/      }     }      else      break;   /*村庄之间都已连通,则直接跳出循环*/}printf("%d\n",sum);}return 0;}

0 0