★ HDU 3917 最大权闭合图模型
来源:互联网 发布:斗鱼 炒股 知乎 编辑:程序博客网 时间:2024/06/05 02:32
题意:n个城市,m个公司修路,如果选择了A公司,则A公司负责的所有路都要修,另外,和A公司有关系的B公司也要选择,(如果A修了(1,2),B修了(2,3),则称A和B有关系,关系有方向),此题为最大权闭合图模型,另外,将税收和代价可以合并为一个点,因为选择了该点的税收,则代价也必须选,这样可以减少点的个数。
代码:
//Isap算法,复杂度O(n^2m)#pragma comment(linker,"/STACK:102400000,102400000")#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#include <vector>#include <string>#include <math.h>#include <queue>#include <stack>#include <map>#include <set>using namespace std;typedef long long ll; //记得必要的时候改成无符号const int maxn=5005;const int maxm=1000005;const int INF=1000000000;struct EdgeNode{ int from; int to; int cost; int next;}edge[maxm];int head[maxn],cnt;void add(int x,int y,int z){ edge[cnt].from=x;edge[cnt].to=y;edge[cnt].cost=z;edge[cnt].next=head[x];head[x]=cnt++; edge[cnt].from=y;edge[cnt].to=x;edge[cnt].cost=0;edge[cnt].next=head[y];head[y]=cnt++; //printf("%d %d %d\n",x,y,z);}void init(){ cnt=0; memset(head,-1,sizeof(head));}int S,T,n,m;int d[maxn],gap[maxn],curedge[maxn],pre[maxn];//curedge[]为当前弧数组,pre为前驱数组int sap(int S,int T,int n) //n为点数{ int cur_flow,flow_ans=0,u,tmp,neck,i; memset(d,0,sizeof(d)); memset(gap,0,sizeof(gap)); memset(pre,-1,sizeof(pre)); for(i=0;i<=n;i++)curedge[i]=head[i]; //初始化当前弧为第一条邻接表 gap[0]=n; u=S; while(d[S]<n) //当d[S]>=n时,网络中肯定出现了断层 { if(u==T) { cur_flow=INF; for(i=S;i!=T;i=edge[curedge[i]].to) { //增广成功,寻找瓶颈边 if(cur_flow>edge[curedge[i]].cost) { neck=i; cur_flow=edge[curedge[i]].cost; } } for(i=S;i!=T;i=edge[curedge[i]].to) { //修改路径上的边容量 tmp=curedge[i]; edge[tmp].cost-=cur_flow; edge[tmp^1].cost+=cur_flow; } flow_ans+=cur_flow; u=neck; //下次增广从瓶颈边开始 } for(i=curedge[u];i!=-1;i=edge[i].next) if(edge[i].cost&&d[u]==d[edge[i].to]+1) break; if(i!=-1) { curedge[u]=i; pre[edge[i].to]=u; u=edge[i].to; } else { if(0==--gap[d[u]])break; //gap优化 curedge[u]=head[u]; for(tmp=n,i=head[u];i!=-1;i=edge[i].next) if(edge[i].cost) tmp=min(tmp,d[edge[i].to]); d[u]=tmp+1; ++gap[d[u]]; if(u!=S)u=pre[u]; //重标号并且从当前点前驱重新增广 } } return flow_ans;}int zhi[maxn];struct q{ int v,bj; q(){}; q(int v,int bj):v(v),bj(bj){}};vector<q>V[maxn];int main(){ int ans,i,x,y,c,w,k,j; while(~scanf("%d%d",&n,&m)&&(n+m)) { ans=0; for(i=1;i<=n;i++)V[i].clear(); memset(zhi,0,sizeof(zhi)); init(); S=0; T=m+1; for(i=1;i<=m;i++){ scanf("%d",&x); add(S,i,x); ans+=x; } scanf("%d",&k); for(i=1;i<=k;i++){ scanf("%d%d%d%d",&x,&y,&c,&w); V[x].push_back(q(y,c)); zhi[c]+=w; } for(i=1;i<=m;i++)add(i,T,zhi[i]); for(i=1;i<=n;i++){ for(j=0;j<V[i].size();j++){ for(k=0;k<V[V[i][j].v].size();k++){ if(V[i][j].bj!=V[V[i][j].v][k].bj) add(V[i][j].bj,V[V[i][j].v][k].bj,INF); } } } n=T+1; printf("%d\n",ans-sap(S,T,n)); }}
0 0
- ★ HDU 3917 最大权闭合图模型
- hdu 3917 (最大权闭合图)
- hdu 3917 最大权闭合图
- hdu 3879(最小割模型求解最大权闭合图)
- HDU 3917 Road constructions 最小割模型最大权闭合图
- 多校HDU 3917 Road constructions(最大权闭合图)
- hdu 3917 Road constructions 最大权闭合图
- 【HDU】3917 Road constructions 最大权闭合子图
- Road constructions (hdu 3917 最大权闭合图)
- HDU 3917 Road constructions(最大权闭合图)
- hdu 3996 最大权闭合图
- hdu 3879 (最大权闭合图)
- hdu 3061 (最大权闭合图)
- hdu 3996 (最大权闭合图)
- hdu 3061 Battle(最大权闭合图)
- hdu 3996 最大权闭合子图
- hdu 3879 最大权闭合子图
- hdu 3061 Battle 最大权闭合图
- linux中的分段和分页
- Matlab学习笔记 sparse与full函数
- hdu 2813 One fihgt one(二分图最小权匹配KM)
- 【UI布局】FrameLayout与gravilty例子
- HDU 2282 Chocolate(二分图最优匹配)
- ★ HDU 3917 最大权闭合图模型
- 大学四年规划之印刷工程专业
- 谈谈产品开发团队的配置管理规则
- piwik api: 调用api数据
- 如何在在改版的spring官网下载jar
- java基础:关于java流与文件操作
- python 学习交流
- WF4之持久化
- CF 46 D Parking Lot(线段树区间合并)