1001 ProblemA

题意:
有N个村庄 编号是从1到N,需要把他们连通起来,如果1到2和2到3有路,1到3也是连通的,给出每个村庄之间的距离,求修路最少要修多长才能使所有村庄连通。
思路:
这是一个最小生成树的问题,用Prim算法,选定一个点把与这个点相关的最小的边连上,然后再选与这两个点相关的最小的边连上,以此类推,直到全连上。
我本来用并查集做的,按边排序,把最小的边连上,总是超时,就又换了种思路。

#include<iostream>
#include<fstream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 110;
const int INF = 0x3f3f3f3f;
int n, ans;
int map[N][N], dis[N], vis[N];
void Prim() {
    int i;
    for (i = 1;i <= n;i++) {
        dis[i] = map[1][i];
        vis[i] = 0;
    }
    vis[1] = 1;
    int j, k, tmp;
    for (i = 1;i <= n;i++) 
    {
        tmp = INF;
        for (j = 1;j <= n;j++)
            if (!vis[j] && tmp>dis[j]) 
            {
                k = j;
                tmp = dis[j];
            }
        if (tmp == INF)
            break;
        vis[k] = 1;
        ans += dis[k];
        for (j = 1;j <= n;j++)
            if (!vis[j] && dis[j]>map[k][j])
                dis[j] = map[k][j];
    }
}

int main() {

    fstream cin("E:/C++/IN/aaa.txt");

    while (cin>>n) {
        for (int i = 1;i <= n;i++)
            for (int j = 1;j <= n;j++)
                cin>>map[i][j];
        int q, a, b;
     cin>>q;
        while (q--) {
            cin >> a >> b;
            map[a][b] = map[b][a] = 0;
        }
        ans = 0;
        Prim();
        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/s7799653/article/details/51648749