程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 2421 Constructing Roads 修建道路 最小生成樹 Kruskal算法

POJ 2421 Constructing Roads 修建道路 最小生成樹 Kruskal算法

編輯:C++入門知識

POJ 2421 Constructing Roads 修建道路 最小生成樹 Kruskal算法


題目鏈接:POJ 2421 Constructing Roads 修建道路

Constructing Roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19698 Accepted: 8221

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

Source

PKU Monthly,kicc

題意:

有N個村莊,編號從1到N。現需要在這N個村莊之間修路,使得任何兩個村莊之間都可以連通。稱A、B兩個村莊是連通的,當且僅當A與B有路直接連接,或者存在村莊C,使得A和C兩村莊之間有路連接,且C和B之間有路連接。已知某些村莊之間已經有路直接連接了,試修建一些路使得所有村莊都是連通的、且修路總長度最短。

分析:

最小生成樹問題,已經修好路的村莊之間將他們的長度置為0,然後再用Kruskal算法求解。

代碼:

#include 
#include 
#include 
#include 
using namespace std;

#define maxn 110
#define maxm 5050
int parent[maxn];
int g[maxn][maxn];
int m, ans;

struct edge
{
    int u, v, w;
}EG[maxm];
bool cmp(edge a, edge b)
{
    return a.w < b.w;
}
int Find(int x)
{
    if(parent[x] == -1) return x;
    return Find(parent[x]);
}

void Kruskal()
{
    memset(parent, -1, sizeof(parent));
    ans = 0;
    sort(EG, EG+m, cmp);
    for(int i = 0; i < m; i++)
    {
        int t1 = Find(EG[i].u), t2 = Find(EG[i].v);
        if(t1 != t2)
        {
            ans += EG[i].w;
            parent[t1] = t2;
        }
    }
}
int main()
{
    int n, q, a, b;
    while(~scanf("%d", &n))
    {
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                scanf("%d", &g[i][j]);
        scanf("%d", &q);
        while(q--)
        {
            scanf("%d%d", &a, &b);
            g[a][b] = g[b][a] = 0;
        }
        m = 0;
        for(int i = 1; i <= n; i++)
            for(int j = i+1; j <= n; j++)
            {
                EG[m].u = i;
                EG[m].v = j;
                EG[m].w = g[i][j];
                m++;
            }
        Kruskal();
        printf("%d\n", ans);
    }
    return 0;
}



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved