[最小k度限制生成树] POJ 1639 Picnic Planning
2016-12-11 10:43
471 查看
论文:汪汀--最小生成树问题的拓展
另见:http://blog.csdn.net/jarily/article/details/8779621 http://www.cnblogs.com/ylfdrib/archive/2010/08/21/1805505.html
主要思想:先求出最小m度限制生成树 由最小m度限制生成树找环得到最小m+1度限制生成树
实现么 Prime/Kruskal dfs/DP 皆可
另见:http://blog.csdn.net/jarily/article/details/8779621 http://www.cnblogs.com/ylfdrib/archive/2010/08/21/1805505.html
主要思想:先求出最小m度限制生成树 由最小m度限制生成树找环得到最小m+1度限制生成树
实现么 Prime/Kruskal dfs/DP 皆可
#include<cstdio> #include<cstdlib> #include<algorithm> #include<map> #include<string> #include<iostream> #include<cstring> #define cl(x) memset(x,0,sizeof(x)) using namespace std; const int N=105; struct edges{ int u,v,w,idx; edges(int u=0,int v=0,int w=0,int idx=0):u(u),v(v),w(w),idx(idx){ } bool operator < (const edges &B) const{ return w<B.w; } }Ed[N*N*2]; map<string,int> Map; int n,m; inline int Num(string s){ if (Map.find(s)!=Map.end()) return Map[s]; Map[s]=++n; return n; } namespace Tset{ int fat ; inline void init(int n){ for (int i=1;i<=n;i++) fat[i]=i; } inline int Fat(int u){ return u==fat[u]?u:fat[u]=Fat(fat[u]); } inline bool Merge(int x,int y){ x=Fat(x); y=Fat(y); if (x==y) return 0; fat[x]=y; return 1; } } struct edge{ int u,v,w,next; }G[N*N*2]; int head ,inum=1; int tag[N*N*2]; inline void add(int u,int v,int w,int p){ G[p].u=u; G[p].v=v; G[p].w=w; G[p].next=head[u]; head[u]=p; } int T,K; int f ; #define V G[p].v inline void dfs(int u,int fa){ for (int p=head[u];p;p=G[p].next) if (V!=fa && tag[p]){ if (u!=1) if (f[u]==-1 || G[p].w>G[f[u]].w) f[V]=p; else f[V]=f[u]; dfs(V,u); } } int Ans=0; int main(){ using namespace Tset; string su,sv; int iu,iv,iw; freopen("t.in","r",stdin); freopen("t.out","w",stdout); while (~scanf("%d",&m)){ Map["Park"]=n=1; for (int i=1;i<=m;i++){ cin>>su>>sv>>iw; iu=Num(su); iv=Num(sv); add(iu,iv,iw,++inum); add(iv,iu,iw,++inum); Ed[i]=edges(iu,iv,iw,i); } cin>>K; sort(Ed+1,Ed+m+1); init(n); for (int i=1;i<=m;i++){ if (Ed[i].u==1 || Ed[i].v==1) continue; if (Merge(Ed[i].u,Ed[i].v)) tag[Ed[i].idx<<1]=tag[Ed[i].idx<<1|1]=1,Ans+=Ed[i].w; } for (int i=1;i<=m;i++){ if (!(Ed[i].u==1 || Ed[i].v==1)) continue; if (Merge(Ed[i].u,Ed[i].v)) tag[Ed[i].idx<<1]=tag[Ed[i].idx<<1|1]=1,++T,Ans+=Ed[i].w; } for (int i=T+1;i<=K;i++){ memset(f,-1,sizeof(f)); dfs(1,0); int t,r,maxv=-1<<30; for (int p=head[1];p;p=G[p].next) if (!tag[p] && f[V]!=-1 && maxv<G[f[V]].w-G[p].w) maxv=G[f[V]].w-G[p].w,t=f[V],r=p; if (maxv<=0) break; Ans-=maxv; tag[r]=tag[r^1]=1; tag[t]=tag[t^1]=0; } printf("Total miles driven: %d\n",Ans); cl(head); inum=1; cl(tag); T=0; Ans=0; Map.clear(); } return 0; }
相关文章推荐
- 【POJ 1639】 Picnic Planning (最小k度限制生成树)
- poj1639 Picnic Planning 最小度数限制生成树
- POJ 1639:Picnic Planning(最小度限制生成树)
- poj 1639 Picnic Planning 最小K度限制生成树
- POJ 1639 Picnic Planning(最小度限制生成树)
- poj1639 Picnic Planning 最小度数限制生成树
- poj 1639 Picnic Planning(最小K度限制生成树)
- POJ-1639 Picnic Planning (最小度限制生成树)(模板题)
- POJ 1639 Picnic Planning (k度限制最小生成树)
- poj1639 Picnic Planning 最小度数限制生成树
- POJ 1639 Picnic Planning(初遇最小度限制生成树)
- POJ --- 1639 【k度限制最小生成树】
- POJ1639 Picnic Planning —— 根节点度数有限制的最小生成树
- 【POJ】1639 Picnic Planning 度限制最小生成树
- poj 1639 Picnic Planning 最小k度生成树
- POJ 1639 最小度限制生成树
- poj_1639 Picnic Planning(度限制最小生成树)
- POJ 1639 度限制最小生成树Prim
- poj1639 Picnic Planning,K度限制生成树
- POJ 1639 Picnic Planning【度限制最小生成树】