hdu1863最小生成树krus模板
Posted iEdson
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu1863最小生成树krus模板相关的知识,希望对你有一定的参考价值。
最小生成树的定义:权值和最小的连通路
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; }
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; }
krus可能是从森林合并到树,prim必然是一颗树拓展
以上是关于hdu1863最小生成树krus模板的主要内容,如果未能解决你的问题,请参考以下文章