hdu1863最小生成树krus模板&prim模板

最小生成树的定义:权值和最小的连通路

krus:每一步寻找原图最短路径(但是要安全边)加入 判断安全边可以用并查集

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

//#define EdsonLin

#ifdef EdsonLin
#define debug(...) fprintf(stderr,__VA_ARGS__)
#else
#define debug(...)
#endif //EdsonLin

typedef long long ll;
typedef double db;
const int inf = 0x3f3f3f;
const int MAXN = 1e3;
const int MAXNN = 2e6+100;
//const int MAXM = 1e6;
//const int MAXM = 3e4+100;
const int MOD = 1000000007;
const db eps = 1e-3;
#define PB push_back

int readint(){int x;scanf("%d",&x);return x;}

struct kruskal{
    int n,m;
    struct edge{
        int u,v,dist;
    };
    int father[MAXN];
    vector<edge>E;
    void init(int n){this->n = n;for(int i=0;i<n;i++)father[i]=i;E.clear();}
    static bool cmp(edge a,edge b){return a.dist<b.dist;}

    int Find(int x){
        return x==father[x]?x:Find(father[x]);
    }
    void Union(int u,int v){
        father[u] = Find(u);
        father[v] = Find(v);
        father[father[u]] = father[v];
    }

    void addge(int u,int v,int dist){
        edge a;
        a.u = u;
        a.v = v;
        a.dist = dist;
        E.PB(a);
    }


    void mst(int &tol){
        sort(E.begin(),E.end(),cmp);
        for(std::vector<edge>::iterator li=E.begin();li!=E.end();li++){
            int u = (*li).u,v = (*li).v;
            if(Find(u)!=Find(v)){
                Union(u,v);
                tol += (*li).dist;
            }
        }
    }
    bool check(){
        int fa = Find(0);
        bool sg = true;;
        for(int i=1;i<n;i++){
            if(fa!=Find(i)){
                sg = false;
                break;
            }
        }
        return sg;
    }

}solver;

int main()
{
    #ifdef EdsonLin
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        int _time_ed = clock();
    #endif //EdsonLin

    int n,m,tol;

    while(scanf("%d%d",&m,&n)!=EOF&&m){
        solver.init(n);
        int u,v,dis;
        tol = 0;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&dis);
            u--,v--;
            solver.addge(u,v,dis);
        }
        solver.mst(tol);
        if(!solver.check()){
            cout<<"?"<<endl;
            continue;
        }
        cout<<tol<<endl;
    }


    #ifdef EdsonLin
        debug("time: %d\n",int(clock()-_time_ed));
    #endif //EdsonLin
   // cout << "Hello world!" << endl;
    return 0;
}
krus

 prim:每一步向A树加新边

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

//#define EdsonLin

#ifdef EdsonLin
#define debug(...) fprintf(stderr,__VA_ARGS__)
#else
#define debug(...)
#endif //EdsonLin

typedef long long ll;
typedef double db;
const int inf = 0x3f3f3f3f;
const int MAXN = 1e3;
const int MAXNN = 2e6+100;
//const int MAXM = 1e6;
//const int MAXM = 3e4+100;
const int MOD = 1000000007;
const db eps = 1e-3;
#define PB push_back

int readint(){int x;scanf("%d",&x);return x;}

struct prime{
    int n,m;
    struct edge{
        int u,v,dist,next;
    };
    struct heapnode{
        heapnode(){dist=inf;};
        int u;
        int dist;
        bool operator < (const heapnode& rhs) const{
            return dist>rhs.dist;
        }
    };
    int first[MAXN];
    int top;
    vector<edge>E;
    int d[MAXN],fa[MAXN];
    void init(int n){this->n = n;E.clear();memset(first,-1,sizeof(first));top=0;memset(d,0x3f,sizeof d);}
    static bool cmp(edge a,edge b){return a.dist<b.dist;}

    void addge(int u,int v,int dist){
        edge a;
        a.u = u;
        a.v = v;
        a.dist = dist;
        a.next = first[u];
        first[u] = top++;
        E.PB(a);
    }


    void mst(int r){
        int done[MAXN];
        int inq[MAXN];
        priority_queue<heapnode>Q;
        heapnode a;
        for(int i=0;i<n;i++){inq[i]=1;done[i]=0;fa[i]=-1;if(i==r)a.dist=0;else a.dist=inf;a.u=i;Q.push(a);}
        d[r] = 0;
        while(!Q.empty()){
            heapnode a = Q.top();
            Q.pop();
            int u = a.u;
            if(done[u])continue;
            inq[u] = 0;
            done[u] = 1;
            for(int i=first[u];i!=-1;i=E[i].next){
                int v = E[i].v;
                if(inq[v]&&d[v]>E[i].dist){d[v]=E[i].dist;a.u=v;a.dist=d[v];Q.push(a);fa[v]=u;}
            }
        }

    }
    bool check(int &tol){
        int rt=0;
        for(int i=0;i<n;i++){
            tol += d[i];
            if(fa[i]==-1)
                rt++;
        }
        if(rt>1)return false;
        return true;
    }


}solver;

int main()
{
    #ifdef EdsonLin
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        int _time_ed = clock();
    #endif //EdsonLin

    int n,m,tol;
    while(scanf("%d%d",&m,&n)!=EOF&&m){
        solver.init(n);
        int u,v,dis;
        tol = 0;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&dis);
            u--,v--;
            solver.addge(u,v,dis);
            solver.addge(v,u,dis);
        }
        solver.mst(0);
        if(!solver.check(tol)){
            cout<<"?"<<endl;
            continue;
        }
        cout<<tol<<endl;
    }


    #ifdef EdsonLin
        debug("time: %d\n",int(clock()-_time_ed));
    #endif //EdsonLin
   // cout << "Hello world!" << endl;
    return 0;
}
prim

 

krus可能是从森林合并到树,prim必然是一颗树拓展

posted @ 2016-06-15 01:23  iEdson  阅读(680)  评论(0编辑  收藏  举报