题意: 有n个基站可以建立,然后m个团体会使用这些基站进行工作,地i个团体会适应Ai Bi 这两个基站, 如果建成收益Ci,  第j个基站花费Pj,求如何建立使得收益最大,

将每个团体看以一个点,然后从这个点出发向那两个点建一条边,他自己想s建立一个为Ci的边,第j个基站想t建立一个容量为Pj的边,跑一遍最小割,然后所有正权减去这个最小割得到答案

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int maxn=;
const int INF=;
struct Dinic
{ struct Edge{
int from,to,cap,flow;
Edge(int cfrom=,int cto=,int ccap=,int cflow=)
{
from=cfrom; to=cto; cap=ccap; flow=cflow;
}
};
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
void init(int n)
{
m=;
for(int i=; i<=n; i++)G[i].clear();
edges.clear();
}
void addEdge(int from,int to, int cap)
{
edges.push_back(Edge(from,to,cap,) );
edges.push_back(Edge(to,from,,));
m+=;
G[from].push_back(m-);
G[to].push_back(m-);
}
bool BFS()
{
memset(vis,,sizeof(vis));
queue<int>Q;
Q.push(s);
d[s]=;
vis[s]=;
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=; i<G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if(vis[e.to]==false&&e.cap>e.flow)
{
vis[e.to]=;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x,int a)
{
if(x==t||a==)return a;
int flow=,f;
for(int &i=cur[x]; i<G[x].size(); i++)
{
Edge &e=edges[G[x][i]];
if(d[x]+==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>)
{
e.flow+=f;
edges[G[x][i]^].flow-=f;
flow+=f;
a-=f;
if(a==)break;
}
}
return flow;
}
int Maxflow(int s,int t)
{
this->s=s;this->t=t;
int flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow+=DFS(s,INF);
}
return flow;
}
}T;
int P[maxn];
int A[maxn],B[maxn],X[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==)
{
int S=;
T.init(n+m+);
int ss=n+m+,tt=n+m+;
for(int i=; i<=n; i++)
{
scanf("%d",&P[i]);
S+=P[i];
T.addEdge(i,tt,P[i]);
}
int S1=;
for(int i=; i<=m; i++)
{ scanf("%d%d%d",&A[i],&B[i],&X[i]);
T.addEdge(ss,n+i,X[i]);
S+=X[i];
S1+=X[i];
}
for(int j=; j<=m; j++)
{
T.addEdge(n+j,A[j],S);
T.addEdge(n+j,B[j],S);
}
int ans=T.Maxflow(ss,tt);
printf("%d\n",S1-ans);
}
return ;
}

ISAP

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int maxn=;
const int INF=;
struct ISAP
{ struct Edge{
int from,to,cap,flow;
Edge(int cfrom=,int cto=,int ccap=,int cflow=)
{
from=cfrom; to=cto; cap=ccap; flow=cflow;
}
};
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int p[maxn];
int num[maxn];
void init(int n)
{
m=;
this->n=n;
for(int i=; i<=n; i++)G[i].clear();
edges.clear();
}
void addEdge(int from,int to, int cap)
{
edges.push_back(Edge(from,to,cap,) );
edges.push_back(Edge(to,from,,));
m+=;
G[from].push_back(m-);
G[to].push_back(m-);
}
void BFS()
{
memset(vis,,sizeof(vis));
queue<int>Q;
Q.push(t);
d[t]=;
vis[t]=;
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=; i<G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if(vis[e.to]==false)
{
vis[e.to]=;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
}
int Augment()
{
int x=t,a=INF;
while(x!=s)
{
Edge &e=edges[p[x]];
a=min(a,e.cap-e.flow);
x=edges[p[x]].from;
}
x=t;
while(x!=s)
{
edges[p[x]].flow+=a;
edges[p[x]^].flow-=a;
x=edges[p[x]].from;
}
return a;
}
int Maxflow(int s,int t)
{
this->s=s;this->t=t;
int flow=;
BFS();
memset(num,,sizeof(num));
for(int i=; i<=n; i++)num[d[i]]++;
int x=s;
memset(cur,,sizeof(cur));
while(d[s]<n)
{
if(x==t)
{
flow+=Augment();
x=s;
}
int ok=;
for(int i=cur[x]; i<G[x].size(); i++)
{
Edge &e=edges[G[x][i]];
if(e.cap>e.flow&&d[x]==d[e.to]+)
{
ok=;
p[e.to]=G[x][i];
cur[x]=i;
x=e.to;
break;
}
}
if(ok==)
{
int m=n-;
for(int i=; i<G[x].size(); i++)
{
Edge &e=edges[G[x][i]];
if(e.cap>e.flow)m=min(m,d[e.to]);
}
if(--num[d[x]]==)break;
num[d[x]=m+]++;
cur[x]=;
if(x!=s)x=edges[p[x]].from;
}
}
return flow;
}
}T;
int P[maxn];
int A[maxn],B[maxn],X[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==)
{
int S=;
T.init(n+m+);
int ss=n+m+,tt=n+m+;
for(int i=; i<=n; i++)
{
scanf("%d",&P[i]);
S+=P[i];
T.addEdge(i,tt,P[i]);
}
int S1=;
for(int i=; i<=m; i++)
{ scanf("%d%d%d",&A[i],&B[i],&X[i]);
T.addEdge(ss,n+i,X[i]);
S+=X[i];
S1+=X[i];
}
for(int j=; j<=m; j++)
{
T.addEdge(n+j,A[j],S);
T.addEdge(n+j,B[j],S);
}
int ans=T.Maxflow(ss,tt);
printf("%d\n",S1-ans);
}
return ;
}

hdu3879 最大权闭合回路的更多相关文章

  1. poj2987 求最大权闭合回路

    建图差不多和以前做的差不多,就是最后询问这个闭合子图有多少个的时候,只要输出这个图的S集合,就是进行dfs能遍历到的点一定在S集合中,不能遍历到的点在T集合中 #include <iostrea ...

  2. hdu3879 最大权闭合图

    若a,b 2点能够相连,那么可以得到ci的价值,也就是说a,b是得到c的前提条件,对于每一个点,又有耗费. 对于本题,先求出最多能够得到的利益有多少,最小割=未被 选的用户的收益之和 + 被选择的站点 ...

  3. hdu3879 Base Station 最大权闭合子图 边权有正有负

    /** 题目:hdu3879 Base Station 最大权闭合子图 边权有正有负 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 题意:给出n个 ...

  4. 最大权闭合图最大获益(把边抽象为点)HDU3879

    题意:给出一个无向图,每个点都有点权值代表花费,每条边都有利益值,代表形成这条边就可以获得e[i]的利益,问选择那些点可以获得最大利益是多少? 分析:把边抽象成点,s与该点建边,容量是利益值,每个点与 ...

  5. hdu 3879 hdu 3917 构造最大权闭合图 俩经典题

    hdu3879  base station : 各一个无向图,点的权是负的,边的权是正的.自己建一个子图,使得获利最大. 一看,就感觉按最大密度子图的构想:选了边那么连接的俩端点必需选,于是就以边做点 ...

  6. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  7. POJ2195 Going Home[费用流|二分图最大权匹配]

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22088   Accepted: 11155 Desc ...

  8. HDU 3879 Base Station(最大权闭合子图)

    经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...

  9. HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...

随机推荐

  1. PSU/OPATCH/OJVM下载页面及安装方式(最实用版)

    中文版:数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1) Download Reference for Or ...

  2. LeetCode 637 Average of Levels in Binary Tree 解题报告

    题目要求 Given a non-empty binary tree, return the average value of the nodes on each level in the form ...

  3. Interceptor的基本介绍和使用

    简介 java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Act ...

  4. 离线应用与客户端存储(cookie storage indexedDB)

    离线检测 HTML5定义一个属性:navigator.onLine的属性.这个属性值为true,表示设备在线,值为false,表示设备离线.为了更好的确定网络是否可用,HTML5还定义了两个事件.这两 ...

  5. Spring MVC中前端控制器拦截问题

    <!-- 前端控制器 --> <servlet> <servlet-name>ssm</servlet-name> <servlet-class& ...

  6. iptables编写规则

    [-t 表名]:该规则所操作的哪个表,可以使用filter.nat等,如果没有指定则默认为filter -A:新增一条规则,到该规则链列表的最后一行 -I:插入一条规则,原本该位置上的规则会往后顺序移 ...

  7. Python3学习之路~6.4 析构函数

    析构函数是在实例释放.销毁的时候执行的,通常用于做一些收尾工作.比如说,关闭一些数据库连接.打开的临时文件等. #Author:Zheng Na class Role: # 构造函数 def __in ...

  8. zookeeper(百度百科http://baike.baidu.com/view/3061646.htm?fr=aladdin)

    ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂易出错的关键服务 ...

  9. python的__all__

    用来暴露接口 控制 from xxx import * 的行为 代码中当然是不提倡用 from xxx import * 的写法的,但是在 console 调试的时候图个方便还是很常见的.如果一个模块 ...

  10. content_type

    1.作用 将app名称与其中表关系进行保存 在models创建表时,关联到ContentType并不会产生实际的字段 2.使用 在models中代码 from django.db import mod ...