HDU - 3879 Base Station 最大权闭合子图
2017-12-18 20:16
357 查看
最大权闭合子图:在一个图中,我们选取一些点构成集合,记为V,且集合中的出边(即集合中的点的向外连出的弧),所指向的终点(弧头)也在V中,则我们称V为闭合图。最大权闭合图即在所有闭合图中,集合中点的权值之和最大的V,我们称V为最大权闭合图。
图中最大权闭合子图为{3,4,5}
题意:有n个城市,每个城市可以花费p[i]修建一个通信站,如果a和b都建了通信站的话就可以得到c的利润,求最大利润是多少.
可以把m条边看做为一个点,这个点连接着a和b,权值为INF,边和源点相连,点和汇点相连。
图中最大权闭合子图为{3,4,5}
题意:有n个城市,每个城市可以花费p[i]修建一个通信站,如果a和b都建了通信站的话就可以得到c的利润,求最大利润是多少.
可以把m条边看做为一个点,这个点连接着a和b,权值为INF,边和源点相连,点和汇点相连。
#include<bits/stdc++.h> using namespace std; const int N=55000+10; const int M=25000000+10; const int INF=0x3f3f3f3f; int n,m; struct node { int u,v,next,cap; } eage[M*2]; int source,sink; int cur ,dep ,gap ; int head ; int top; int S ; int p ; void Add(int u,int v,int w) { eage[top].u=u; eage[top].v=v; eage[top].cap=w; eage[top].next=head[u]; head[u]=top++; eage[top].u=v; eage[top].v=u; eage[top].cap=0; eage[top].next=head[v]; head[v]=top++; } void BFS() { queue<int>q; memset(dep,-1,sizeof(dep)); memset(gap,0,sizeof(gap)); gap[0]=1; dep[sink]=0; q.push(sink); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i!=-1; i=eage[i].next) { int v=eage[i].v; if(dep[v]==-1) { q.push(v); dep[v]=dep[u]+1; gap[dep[v]]++; } } } } int Sap() { BFS(); memcpy(cur,head,sizeof(head)); int tot=0; int u=source; int ans=0; while(dep[source]<n) { if(u==sink) { int Min=INF; int inser; for(int i=0; i<=tot-1; i++) { if(Min>eage[S[i]].cap) { Min=eage[S[i]].cap; inser=i; } } for(int i=0; i<=tot-1; i++) { eage[S[i]].cap-=Min; eage[S[i]^1].cap+=Min; } ans+=Min; tot=inser; u=eage[S[tot]].u; } if(u!=sink&&gap[dep[u]-1]==0) break; int v; int i; for(i=cur[u]; i!=-1; i=eage[i].next) { v=eage[i].v; if(eage[i].cap&&dep[v]+1==dep[u]) { break; } } if(i!=-1) { cur[u]=i; S[tot++]=i; u=v; continue; } int Min=n; for(int i=head[u]; i!=-1; i=eage[i].next) { int v=eage[i].v; if(eage[i].cap&&dep[v]<Min) { Min=dep[v]; cur[u]=i; } } gap[dep[u]]--; dep[u]=Min+1; gap[dep[u]]++; if(u!=source)u=eage[S[--tot]].u; } return ans; } int main() { while(~scanf("%d%d",&n,&m)) { memset(head,-1,sizeof(head)); top=0; source=0; sink=n+m+1; for(int i=1;i<=n;i++) { scanf("%d",&p[i]); Add(m+i,sink,p[i]); } int sum=0; for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); sum+=w; Add(source,i,w); Add(i,m+u,INF); Add(i,m+v,INF); } n=n+m+2; printf("%d\n",sum-Sap()); } return 0; }
相关文章推荐
- Base Station HDU - 3879(最大权闭合子图)
- 【HDU】3879 Base Station 最大权闭合子图
- hdu 3879 Base Station bzoj 1497 最大获利问题 最大权闭合子图
- HDU 3879 Base Station 最大权闭合子图
- hdu 3879 Base Station 最大权闭合图
- HDU 3879 Base Station 最大权闭合图
- HDU 3897 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 有模板!
- HDOJ 3879 - Base Station 最大权闭合子图(最小割解决)
- HDU 3879 Base Station 最大权闭合图
- HDU 3879 Base Station 最大权闭合图
- [最大权闭合图]hdoj 3879:Base Station
- HDU 3879 Base Station(最大权闭合子图)
- HDU 3879 Base Station【最大权闭包】
- Hdu3879 Base Station 最大权闭合子图 最大获利