Constructing Roads POJ

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

题意:有不超过100个村庄,输入第一行一个数n表示村庄数,然后有n行每行都是第i个村庄与其他村庄的之间的距离,然后再一行有一个数m表示已经修建的道路数,然后往下m行,每行两个数表示在这两个村庄之间已经修建好了道路。
问在让所有的村庄都能够连接在一起的前提下至少还要修建多长的道路。

思路:题意可以以变换一下,已经修建好道路的村庄之间是可以不用再连接这两个村庄的,所以我们只需要求剩下的没连接在一起村庄进行最小生成数算法。
首先对村庄间的距离用一个二维数组保存,然后对已经修建好的村庄之间的道路进行标记,再对二维数组到容器的转发中把已经连在一起的村庄合并并不录入这个数据,最后在根据Kruskal算法进行运算。

代码:
  1 #include <cstdio>
  2 #include <fstream>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <deque>
  6 #include <vector>
  7 #include <queue>
  8 #include <string>
  9 #include <cstring>
 10 #include <map>
 11 #include <stack>
 12 #include <set>
 13 #include <sstream>
 14 #include <iostream>
 15 #define mod 998244353
 16 #define eps 1e-6
 17 #define ll long long
 18 #define INF 0x3f3f3f3f
 19 using namespace std;
 20 
 21 //u表示起点,v表示终点,cost表示花费
 22 struct node
 23 {
 24     int u,v;
 25     double cost;
 26 };
 27 //排序,从小到大
 28 bool cmp(node a,node b)
 29 {
 30     return a.cost<b.cost;
 31 }
 32 //存放边的信息
 33 vector<node> ve;
 34 
 35 //fa表示当前i的最远祖先
 36 int fa[110];
 37 //初始化fa,开始时自己是自己的祖先
 38 void init(int qwq)
 39 {
 40     for(int i=0;i<=qwq;i++)
 41     {
 42         fa[i]=i;
 43     }
 44 }
 45 //查找最远祖先,同时进行路径压缩
 46 int find(int x)
 47 {
 48     if(fa[x]==x)
 49     {
 50         return x;
 51     }
 52     return fa[x]=find(fa[x]);
 53 }
 54 //判断最远祖先是否相同
 55 bool che(int x,int y)
 56 {
 57     return find(x)==find(y);
 58 }
 59 //合并x,y,把他们放到同一个家族中
 60 void mer(int x,int y)
 61 {
 62     if(!che(x,y)) 
 63     {
 64         fa[fa[x]]=fa[y];
 65     }
 66     return ;
 67 }
 68 int n,m;
 69 //ma用于保存村庄之间的距离
 70 int ma[105][105];
 71 //bj用于标记已经连接的村庄编号
 72 int bj[105][105];
 73 int main()
 74 {
 75     scanf("%d",&n);
 76     //初始化
 77     init(n);
 78     for(int i=1;i<=n;i++)
 79     {
 80         for(int j=1;j<=n;j++)
 81         {
 82             scanf("%d",&m);
 83             ma[i][j]=m;
 84         }
 85     }
 86     int a,b;
 87     //初始化bj
 88     memset(bj,0,sizeof(bj));
 89     scanf("%d",&m);
 90     for(int i=0;i<m;i++)
 91     {
 92         scanf("%d %d",&a,&b);
 93         //标记,
 94         bj[a][b]=1;
 95         bj[b][a]=1;
 96     }
 97     node no;
 98     for(int i=2;i<=n;i++)
 99     {
100         for(int j=1;j<i;j++)
101         {
102             //当村庄之间没有道路时
103             if(bj[i][j]==0)
104             {
105                 no.u=i;
106                 no.v=j;
107                 no.cost=ma[i][j];
108                 ve.push_back(no);
109             }
110             else
111             {//当村庄之间有道路时,合并这两个村庄
112                 mer(i,j);
113             }
114         }
115     }
116     int ans=0;
117     //排序
118     sort(ve.begin(),ve.end(),cmp);
119     for(int i=0;i<ve.size();i++)
120     {
121         //当两个村庄之间没有连接时
122         if(!che(ve[i].u,ve[i].v))
123         {
124             //合并
125             mer(ve[i].u,ve[i].v);
126             ans+=ve[i].cost;
127         }
128     }
129     printf("%d
",ans);
130     //清除容器内存
131     ve.clear();
132 }


原文地址:https://www.cnblogs.com/mzchuan/p/11729167.html