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算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...
随机推荐
- odoo10如何自定义自动生成单据编号
1.在已有的model中穿件一个字段name class qingjiadan(models.Model): _name = 'qingjia.qingjiadan' name = fields.Ch ...
- 内部排序->插入排序->希尔排序
文字描述 希尔排序又称缩小增量排序,也属于插入排序类,但在时间效率上较之前的插入排序有较大的改进. 从之前的直接插入排序的分析得知,时间复杂度为n*n, 有如下两个特点: (1)如果待排序记录本身就是 ...
- base64简单使用
加密: import base64 import random str ="aqwertyuiopasdfghjklzxcvbnm963.0852741,.;'" a = '人生苦 ...
- C# cmd bcp 导出数据
背景需求:应用系统间数据自动同步处理,要求高效无人工干预 技术实现:C#启动cmd,通过BCP命令传入必要参数,实现数据导出 /// <summary> /// cmd下,启动应用程序命令 ...
- asp.net开发中的问题总结
1.错误摘要 HTTP 错误 404.3 - Not Found 由于扩展配置问题而无法提供您请求的页面 原因:由于刚安装的iis没有注册对应版本的.net导致错误,在vs提供的命令行中输入aspne ...
- RN NetInfo使用
代码: class NetInfoView extends Component { getNetInfo() { //如果是andorid的程序,需要在xml添加获取网络请求权限 NetInfo.fe ...
- 电脑出现 flash update failed 解决方法
笔记本电脑过了一个周末打开时出现以上问题,每次都进入这个界面 解决方法: 拆机,插拨一下内存条,硬盘,就启动了
- oracle安装---yum.sh
!#/bin/bash yum install binutils* -yyum install compat* -yyum install elfutils* -yyum install gcc* - ...
- 2017-2018-2 20165236 实验三《Java面向对象程序设计》实验报告
2017-2018-2 20165236 实验三<Java面向对象程序设计>实验报告 一.实验报告封面 课程:Java程序设计 班级:1652 姓名:郭金涛 ...
- [js]js的表单验证onsubmit方法
http://uule.iteye.com/blog/2183622 表单验证类 <form class="form" method="post" id= ...