HDU 1102 Constructing Roads

来源:互联网 发布:软件实施 编辑:程序博客网 时间:2024/05/13 16:47

利用并查集,判断两点无向图两点之间的连通性, 如果连通,那么权值可以看做是0, 
然后就是最小生成树了, 俄用的是prim
krusal的话本身就用到并查集, 更加直观了~, 减少需要寻找的边数就行了~

#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <string>#include <cmath>#include <vector>#include <map>#include <stack>#include <algorithm>//#include "myAlgorithm.h"#define MAX 105#define OFFENCE (1e9 + 5)#define INF (1e8 + 5)#define eps 1e-9#define Rep(s, e) for( int i = s; i <= e; i++)#define Cep(e, s) for( int j = e; j >= s; j --)#define PI acos(-1.0)//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;int n, q;int mp[MAX][MAX];int fa[MAX];int find(int x){    return x == fa[x]? x: find(fa[x]);}void prim(){    int d[MAX], ans = 0;    bool v[MAX];    Rep(0, n){        d[i] = INF;        v[i] = 0;    }    d[1]= 0;    Rep(1, n){        int min_d = INF, index = 0;        for(int j = 1; j <= n; j++){            if(!v[j] && min_d > d[j]){                min_d = d[j];                index = j;            }        }        if(index){            v[index] = 1;            ans += d[index];            //cout<<index<<" dindex"<<d[index]<<endl;            for(int j = 1; j <= n; j++){                if(!v[j]){                    if(find(index) == find(j)){///如果连通                        //cout<<"index"<<index<<"j"<<j<<endl;                        mp[index][j] = mp[j][index] = 0;                    }                    if(d[j] > mp[index][j]){                        d[j] = mp[index][j];                    }                }            }        }    }    cout<<ans<<endl;}void init(){    Rep(0, n){        Cep(n, 0){            mp[i][j] = INF;        }        fa[i] = i;    }     Rep(1, n){       for(int j = 1; j <= n; j++){            cin>>mp[i][j];// = INF;        }    }    cin>>q;    int a, b;    while(q--){        cin>>a>>b;        int x = find(a), y = find(b);        if(x != y)            fa[x] = y;    }}int main(){    while(cin>>n){        init();        prim();    }    return 0;}/***/