Hdu Base Station (网络流最大权闭合图)
来源:互联网 发布:国考行测技巧知乎 编辑:程序博客网 时间:2024/05/14 17:39
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879
题意:要在 n 个城市修建电台,已知修建每个电台的费用。然后有 m 行,每行三个数 a,b,c,表示如果城市 a 和城市 b 都修建了电台,将带来 c 的收益。求选择一些城市修建电台使得总收益最大。 (0<n<=5000,0<m<=50000).
思路:典型的最大权闭合图。原理参见:http://www.byvoid.com/blog/noi-2006-profit/
#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int INF = 0x6fffffff ; //权值上限const int MAXPT = 57000 ; //顶点数上限const int MAXEG = 1000000 ; //边数上限const int MAXQUE = MAXPT*2 ; // 队列长度/* s = 1 ; // 源点 t = n ; // 汇点*/class MNF_SAP{private: //int m,n; int s,t; int dis[MAXPT]; //距离标号 int pre[MAXPT]; //前置顶点 int flow[MAXPT]; //到当前点为止,所有弧的最小值 int curedge[MAXPT]; //当前弧cur int cnt[MAXPT]; //k标号出现次数 int queue[MAXQUE],front,rear; bool vis[MAXPT]; void BFS () { int i,u; memset(vis,false,sizeof(vis)); front=rear=0; dis[t]=0; vis[t]=true; queue[++rear]=t; while (front!=rear) { u=queue[(++front)%MAXQUE]; for (i=head[u];i!=0;i=edges[i].next) if (vis[edges[i].v]==false && !edges[i].cap) { dis[edges[i].v]=dis[u]+1; vis[edges[i].v]=true; queue[(++rear)%MAXQUE]=edges[i].v; } }for (i=1;i<=n;i++)cnt[dis[i]]++; }public: struct Node { int v,cap,next;Node(){}Node (int _v,int _cap,int _next){v=_v;cap=_cap;next=_next;} }edges[MAXEG]; int n; //总节点数int e; int head[MAXPT];// MNF_SAP(){}// ~MNF_SAP(){}void init (int temp){n=temp;e=2;memset (head,0,sizeof(head));}void Add (int u,int v,int cap) //始,终,量{edges[e]=Node(v,cap,head[u]);head[u]=e++;edges[e]=Node(u,0,head[v]);head[v]=e++;} int SAP () { int u,v,i,maxflow=0; //总最大流 s=1; t=n; u=s; flow[s]=INF; for (i=1;i<=n;i++)curedge[i]=head[i]; //当前弧初始化 BFS (); cnt[0]=n; while (dis[s]<n) { for (i=curedge[u];i!=0;i=edges[i].next) //找允许弧 if (edges[i].cap && dis[edges[i].v]+1==dis[u])break; if (i!=0) //存在允许弧 { curedge[u]=i; //设置当前弧 v=edges[i].v; if (edges[i].cap<flow[u])flow[v]=edges[i].cap; elseflow[v]=flow[u]; //标记当前顶点为止经过的最小弧 u=v; pre[v]=i; //前置顶点边号 if (u==t) { do { edges[pre[u]].cap-=flow[t]; //正向弧减a[t] edges[pre[u]^1].cap+=flow[t]; //通过异或操作找反向弧 u=edges[pre[u]^1].v; } while (u!=s); maxflow+=flow[t]; //memset(flow,0,sizeof(flow)); flow[s]=INF; } } else //不存在允许弧 { if (--cnt[dis[u]]==0)break; //间隙优化 dis[u]=n; curedge[u]=head[u]; for (i=head[u];i!=0;i=edges[i].next) if (edges[i].cap && dis[edges[i].v]+1<dis[u]) dis[u]=dis[edges[i].v]+1; //修改距离标号为 最小的非允许弧加1 cnt[dis[u]]++; if (u!=s)u=edges[pre[u]^1].v; } } return maxflow; }};MNF_SAP ob;int main (){ int n,m,i; int a,b,c; while (~scanf("%d%d",&n,&m)) {int s=1;int t=n+m+2;int sum=0;ob.init(t);for (i=1;i<=n;i++){scanf("%d",&a);ob.Add(s+m+i,t,a);} for (i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c);ob.Add(s,s+i,c);ob.Add(s+i,s+m+a,INF);ob.Add(s+i,s+m+b,INF);sum+=c; }printf("%d\n",sum-ob.SAP()); } return 0;}
- Hdu Base Station (网络流最大权闭合图)
- hdu 3879 Base Station 网络流 最大权闭合图
- HDU 3879 Base Station(最大权闭合)
- HDU 3879 Base Station 最大权闭合图
- hdu 3879 Base Station (最大权闭合图)
- 【HDU】3879 Base Station 最大权闭合子图
- HDU 3879 Base Station 最大权闭合子图
- HDU 3879 Base Station 最大权闭合图
- Base Station (hdu 3879 最大权闭合图)
- 最大权闭合图 hdu 3879 Base Station 有模板!
- hdu 3879 Base Station【最大权闭合图】
- HDU 3879 Base Station 最大权闭合图
- HDU 3879 Base Station(最小割---最大权闭合)
- [最大权闭合图]hdoj 3879:Base Station
- Hdu3879 Base Station 最大权闭合子图 最大获利
- HDU 3879 Base Station 最小割模型 最大权闭合图
- HDU 3996 最大权闭合图 网络流
- HDOJ 3879 - Base Station 最大权闭合子图(最小割解决)
- SQL Server 2008 允许远程连接的解决方法
- JAVA 内部类
- java中list、set和map 的区别
- Struts2中文件上传和多文件上传以及获取HttpServletRequest / HttpSession / ServletContext / HttpServletRespons
- java正则表达式-案例代码
- Hdu Base Station (网络流最大权闭合图)
- POJ2531--Network Saboteur
- c++模板 (STL)
- 浮点数的二进制表示分析
- Struts2_事物管理&文件上传
- Linux启动过程
- TE6410之自己动手编写LED驱动
- buffer与cache
- 进入IT我不曾后悔,希望高人指点迷津