1001 ProblemA

来源:互联网 发布:ipowerl手指充电软件 编辑:程序博客网 时间:2024/05/17 09:18

题意:
有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;}
0 0
原创粉丝点击