hdu3879 最大权闭合回路
题意: 有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 最大权闭合回路的更多相关文章
- poj2987 求最大权闭合回路
建图差不多和以前做的差不多,就是最后询问这个闭合子图有多少个的时候,只要输出这个图的S集合,就是进行dfs能遍历到的点一定在S集合中,不能遍历到的点在T集合中 #include <iostrea ...
- hdu3879 最大权闭合图
若a,b 2点能够相连,那么可以得到ci的价值,也就是说a,b是得到c的前提条件,对于每一个点,又有耗费. 对于本题,先求出最多能够得到的利益有多少,最小割=未被 选的用户的收益之和 + 被选择的站点 ...
- hdu3879 Base Station 最大权闭合子图 边权有正有负
/** 题目:hdu3879 Base Station 最大权闭合子图 边权有正有负 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 题意:给出n个 ...
- 最大权闭合图最大获益(把边抽象为点)HDU3879
题意:给出一个无向图,每个点都有点权值代表花费,每条边都有利益值,代表形成这条边就可以获得e[i]的利益,问选择那些点可以获得最大利益是多少? 分析:把边抽象成点,s与该点建边,容量是利益值,每个点与 ...
- hdu 3879 hdu 3917 构造最大权闭合图 俩经典题
hdu3879 base station : 各一个无向图,点的权是负的,边的权是正的.自己建一个子图,使得获利最大. 一看,就感觉按最大密度子图的构想:选了边那么连接的俩端点必需选,于是就以边做点 ...
- BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...
- POJ2195 Going Home[费用流|二分图最大权匹配]
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22088 Accepted: 11155 Desc ...
- HDU 3879 Base Station(最大权闭合子图)
经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...
- HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法
二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...
随机推荐
- day5_集合
集合也是一种数据类型,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复的数据 集合的作用: 1.它可以把一个列表中重复的数据去掉,而不需要你再写判断---天生去重 2.可以做关系 ...
- day3_字典
一.说明 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示: dict = {key1:value1,key2 ...
- LeetCode 1012 Complement of Base 10 Integer 解题报告
题目要求 Every non-negative integer N has a binary representation. For example, 5 can be represented as ...
- Django2.0跨域请求配置
跨域:通过js或python在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(Django)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- falsk 与 django 过滤器的使用与区别
1,flask中内置的过滤器模板中常用方法: {#过滤器调用方式{{变量|过滤器名称}} #} <!-- safe过滤器,可以禁用转义 --> {{'<strong>hello ...
- LDA学习小记
看到一段对主题模型的总结,感觉很精辟: 如何找到文本隐含的主题呢?常用的方法一般都是基于统计学的生成方法.即假设以一定的概率选择了一个主题,然后以一定的概率选择当前主题的词.最后这些词组成了我们当前的 ...
- centos安装Django之二:pip3安装
前面我们说到了centos安装Django之一:安装openssl,现在我们进入第二阶段pip3安装.两步实现:安装setuptools(pypi),安装pip,下面就和ytkah一起看看配置吧 1. ...
- w97常用功能代码
1,onclick中添加日期控件 2,onpicked事件即是点击控件后触发的事件 3,dp.cal.getNewDateStr()即是点击到的日期字符串 <script> functio ...
- 清空select标签中option选项的3种不同方式
方法一 代码如下:document.getElementById("selectid").options.length = 0; 方法二 代码如下:document.formNam ...
- Java的transient关键字(转)
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看到某个成员变量的同一 ...