HDU 3879 Base Station 最大权闭合子图
2014-09-08 22:58
435 查看
题意:有N个基站和M个用户群。建每个基站有花费。每个用户群需求两个基站,满足这两个基站,会的得到对应的收益。求出收益的最大值
思路:裸的最大权闭合子图,直接套模型即可;
代码如下:
题意:有N个基站和M个用户群。建每个基站有花费。每个用户群需求两个基站,满足这两个基站,会的得到对应的收益。求出收益的最大值
思路:裸的最大权闭合子图,直接套模型即可;
代码如下:
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; struct edge{ int from,to; int cap,flow; edge(int u =0,int v =0,int c=0,int f=0):from(u),to(v),cap(c),flow(f){} }; struct ISAP{ static const int INF = 0x3f3f3f3f; static const int MAX = 500000 * 2;//2倍的边的大小 int head[MAX];//每个节点对应链表的开始位置 int next[MAX];//链表的下一个节点在edges数组的位置 int tot;//edges数组的大小 edge edges[MAX];//储存边的数组 int que[MAX],front,tail;//队列,保存节点 int d[MAX];//距离标号 bool vis[MAX];//访问标记 int num[MAX];//gap优化 int pre[MAX];//增广路中,节点X的前面一个弧的标号 int cur[MAX];//对于每个节点的,处理的当前弧。 int s,t,n;//s源点标号,t汇点标号,n节点总数 void init(int n){ this->n = n;//注意此处的下标问题 memset(head,-1,sizeof(int)*(n+1)); tot = 0;// } void addedge(int from,int to, int cap){ edges[tot] = edge(from,to,cap,0); next[tot] = head[from], head[from] = tot++; edges[tot] = edge(to,from,0,0); next[tot] = head[to],head[to] = tot++; } void bfs(){ memset(vis,0,sizeof(vis)); front = tail = 0; d[t] = 0; vis[t] = true; que[tail++] = t; while(front < tail){ int u = que[front++]; for(int v = head[u]; v != -1; v = next[v]){ edge & e = edges[v^1]; if(e.cap > e.flow && !vis[e.from]){//对处于残余网络中的弧且没访问过的节点处理 d[e.from] = d[u] + 1; vis[e.from] = true; que[tail++] = e.from; } } } } int augment(){ int x = t,a = INF; while(x != s){ edge& e = edges[pre[x]]; a = min(a,e.cap - e.flow); x = e.from; } x = t; while(x != s){ edges[pre[x]].flow += a; edges[pre[x]^1].flow -= a; x = edges[pre[x]].from; } return a; } int maxflow(int s, int t){ this->s = s, this->t = t; memset(num,0,sizeof(num)); int flow = 0; bfs(); for(int i = 0; i <= n; ++i){//注意此处的下标问题 num[d[i]]++; cur[i] = head[i]; } int x = s; while(d[s] < n){ if(x == t){ flow += augment(); x = s; } bool ok = false; for(int &v = cur[x]; v != -1; v = next[v]){ edge& e = edges[v]; if(e.cap > e.flow && d[x] == d[e.to] + 1){ ok = true; pre[x = e.to] = v; break; } } if(!ok){ int m = n - 1; for(int v = head[x]; v != -1; v = next[v]){ edge & e = edges[v]; if(e.cap > e.flow) m = min(m,d[e.to]); } if(--num[d[x]] == 0) break; num[d[x]=m+1]++; cur[x] = head[x]; if(x != s) x = edges[pre[x]].from; } } return flow; } } solver; const int INF = 0x3f3f3f3f; int main(void) { //freopen("main.in","r",stdin); int N,M,p,a,b,c; while(scanf("%d %d", &N, &M) != EOF){ solver.init(N + M + 2); int sum = 0; int s = 0, t = N + M + 1; for(int i = 1 ; i <= N; ++i){ scanf("%d", &p); solver.addedge(i,t,p); } for(int i = 1; i <= M; ++i){ scanf("%d %d %d", &a,&b,&c); solver.addedge(s,N + i,c); solver.addedge(N + i,a,INF); solver.addedge(N + i,b,INF); sum += c; } printf("%d\n",sum - solver.maxflow(s,t)); } return 0; }
相关文章推荐
- HDU - 3879 Base Station 最大权闭合子图
- hdu 3879 Base Station bzoj 1497 最大获利问题 最大权闭合子图
- 【HDU】3879 Base Station 最大权闭合子图
- Base Station HDU - 3879(最大权闭合子图)
- 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 最大权闭合图
- HDU 3879 Base Station 最大权闭合图
- HDU 3897 Base Station (网络流,最大闭合子图)
- hdu 3879 Base Station【最大权闭合图】
- hdu 3879 Base Station 最大权闭合图
- HDU 3879 Base Station(最大权闭合子图)
- Hdu Base Station (网络流最大权闭合图)
- HDU 3879 Base Station 最大权闭包 2011 Multi-University Training Contest 5 - Host by BNU
- hdu3879 Base Station 最大权闭合子图 边权有正有负