poj 1639 Picnic Planning 单度限制的最小生成树
来源:互联网 发布:淘宝忘了用优惠券 编辑:程序博客网 时间:2024/06/05 05:28
题意:
给一个无向图连通图,求它的最小生成树,生成树满足条件点v0的度小于等于limit。
分析:
一般有度限制的最小生成树问题是np完全的,但单点度限制就比较简单了,先在原图上求不含v0的最小生成森林,然后再将森林中每一棵树选一条最短的边连到v0上,设最小生成森林中有k0棵树,如果k0>limit自然无解,否则每次再选增量最小的边连到v0上,同时删除因为加边形成环上的最大边。
代码:
//poj 1639//sepNINE#include <iostream>#include <string>#include <map>#include <algorithm>using namespace std;const int maxN=32;const int maxM=1024;map<string,int> name;int e,parkE,park,n;int vis[maxN];int f[maxN],used[maxM],usedParkE[maxM];int g[maxN][maxN],parent[maxN];struct Edge{int u,v,w;}edge[maxM],parkEdge[maxM];int cmp(Edge a,Edge b){return a.w<b.w;}int find(int u){return f[u]==u?u:f[u]=find(f[u]);}void dfs(int u){for(int i=1;i<=n;++i)if(g[u][i]>0&&parent[i]==0){parent[i]=u;dfs(i);}}void updateTree(){memset(parent,0,sizeof(parent));parent[park]=-1;dfs(park);}int findmax(int v){int maxx=-1,x;while(v!=park){if(maxx<g[v][parent[v]]){maxx=g[v][parent[v]];x=v;}v=parent[v];}return x;}int main(){int i,m,limit;n=0;e=parkE=0;park=-1; cin>>m;while(m--){string a,b;int w;cin>>a>>b>>w;if(name[a]==0) name[a]=++n;if(name[b]==0) name[b]=++n;if(a=="Park") park=name[a];if(b=="Park") park=name[b];int u=name[a],v=name[b];if(park==u||park==v){parkEdge[parkE].u=u;parkEdge[parkE].v=v;parkEdge[parkE].w=w;++parkE;}else{edge[e].u=u;edge[e].v=v;edge[e].w=w;++e;}}cin>>limit;sort(edge,edge+e,cmp);for(i=1;i<=n;++i) f[i]=i;int sum=0;memset(used,0,sizeof(used));memset(g,0,sizeof(g));for(i=0;i<e;++i){int u=edge[i].u,v=edge[i].v;int pa=find(u);int pb=find(v);if(pa==pb)continue;used[i]=1;g[u][v]=g[v][u]=edge[i].w;f[pa]=pb;sum+=edge[i].w; }memset(vis,0,sizeof(vis));sort(parkEdge,parkEdge+parkE,cmp);memset(usedParkE,0,sizeof(usedParkE));int cnt=0;for(i=0;i<parkE;++i){int u=parkEdge[i].u;int v=parkEdge[i].v;int w=parkEdge[i].w;if(u!=park) swap(u,v);if(vis[find(v)]==0){++cnt;vis[find(v)]=1;usedParkE[i]=1;sum+=w;g[u][v]=g[v][u]=w;}}updateTree();while(cnt<limit){int deta=0,minI;for(i=0;i<parkE;++i){if(usedParkE[i]==1)continue;int u=parkEdge[i].u,v=parkEdge[i].v,w=parkEdge[i].w;if(u!=park) swap(u,v);int changeP=findmax(v);int pFather=parent[changeP];if(pFather==park)continue;int t=w-g[changeP][pFather];if(t<deta){deta=t;minI=i;}}if(deta==0)break;else{int u=parkEdge[minI].u;int v=parkEdge[minI].v;int w=parkEdge[minI].w;if(u!=park) swap(u,v);int changeP=findmax(v);int pFather=parent[changeP];g[changeP][pFather]=g[pFather][changeP]=0;g[u][v]=g[v][u]=w;updateTree();usedParkE[minI]=1;sum+=deta;++cnt;} }printf("Total miles driven: %d",sum);return 0;}
0 0
- poj 1639 Picnic Planning 单度限制的最小生成树
- POJ 1639 Picnic Planning【度限制最小生成树】
- POJ 1639:Picnic Planning(最小度限制生成树)
- poj 1639 Picnic Planning(最小度限制生成树)
- POJ 1639 Picnic Planning【度限制最小生成树】
- 【POJ】1639 Picnic Planning 度限制最小生成树
- POJ 1639 Picnic Planning (k度限制最小生成树)
- POJ 1639 Picnic Planning 【最小度限制生成树】
- [最小k度限制生成树] POJ 1639 Picnic Planning
- POJ 1639 Picnic Planning(度限制最小生成树)
- Picnic Planning 最小度限制生成树
- POJ 1639 Picnic Planning(有限制的最小生成树)
- POJ 1639 Picnic Planning(初遇最小度限制生成树)
- poj 1639 Picnic Planning(最小K度限制生成树)
- POJ-1639 Picnic Planning (最小度限制生成树)(模板题)
- Picnic Planning poj 1639 k度限制生成树
- poj 1639 Picnic Planning 最小k度生成树
- POJ1638 Picnic Planning (最小限制度生成树)
- 13周(数组,3的倍数)
- C#拆分器控件Splitcontainer
- POJO是什么
- [leetcode]Construct Binary Tree from Preorder and Inorder Traversal
- Character.isDigit(char ch) &Character.digit('c', 16) & \32
- poj 1639 Picnic Planning 单度限制的最小生成树
- vim编译器设置环境和换行,自动缩进等
- 第二次爬虫任务
- 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理
- 杭电2103
- sqlserver 将15位身份证升级成18位的用户定义函数
- D3DPOOL详解
- Photoshop脚本 > 蒙尘与划痕滤镜的使用
- MFC 对话框Border为None是拖动实现