HDU 3879 Base Station(最大权闭合子图)
经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法。
题意:输入n个点,m条边的无向图。点权为负,边权为正,点权为代价,边权为获益,输出最大获益。
(最大权闭合子图:图中各点的后继必然也在图中)
构图攻略:将边看做点,
若选某条边e[i](u,v,w),则必须选点u,v。由此构成一个有向图。也符合最大权闭合子图模型。
对原本的边e[i](u,v,w)连3条边(S,n+i,w),(n+i,u,inf),(n+i,v,inf)。
对原本的点v,连1条边(v,T,p[v])。
即正权点与源点连,负权点与汇点连。
求最大流,记所有边的正权和为sum,则sum-maxflow就是答案。
显然,sap图的点有n+m+2,边有(n+m*3)*2。
具体证明推导请移步前辈的论文或者别的网站也有很详细的介绍和步骤。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <queue>
using namespace std; #define ll long long
#define MP make_pair #define mxn 56000
#define mxe (51000*4*2)
#define inf 1e9
#define eps 1e-8 struct SAP{
int dis[mxn],pre[mxn],gap[mxn],arc[mxn];
int f[mxe],cap[mxe];
int head[mxn],nxt[mxe],vv[mxe],e;
void init(){e=0;memset(head,-1,sizeof(head));}
void add(int u,int v,int c){
vv[e]=v,cap[e]=c,nxt[e]=head[u],head[u]=e++;
vv[e]=u,cap[e]=0,nxt[e]=head[v],head[v]=e++;
}
ll max_flow(int s,int t,int n){
int q[mxn],j,mindis;
ll ans=0;
int ht=0,tl=1,u,v;
int low;
bool found,vis[mxn];
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
memset(vis,0,sizeof(vis));
memset(arc,-1,sizeof(arc));
memset(f,0,sizeof(f));
q[0]=t;vis[t]=true;dis[t]=0;gap[0]=1;
while(ht<tl){
u=q[ht++];
for(int i=head[u];i!=-1;i=nxt[i]){
v = vv[i];
if(!vis[v]){
vis[v]=true;
dis[v]=dis[u]+1;
q[tl++]=v;
gap[dis[v]]++;
arc[v]=head[v];
}
}
}
u=s;low=inf;pre[s]=s;
while(dis[s]<n){
found=false;
for(int &i=arc[u];i!=-1;i=nxt[i]){
if(dis[vv[i]]==dis[u]-1 && cap[i]>f[i]){
found=true;v=vv[i];
low=min(low,cap[i]-f[i]);
pre[v]=u;u=v;
if(u==t){
while(u!=s){
u=pre[u];
f[arc[u]]+=low;
f[arc[u]^1]-=low;
}
ans+=low;low=inf;
}
break;
}
}
if(found) continue;
mindis=n;
for(int i=head[u];i!=-1;i=nxt[i]){
if(mindis>dis[vv[i]] && cap[i]>f[i]){
mindis=dis[vv[j=i]];
arc[u]=i;
}
}
if(--gap[dis[u]]==0) return ans;
dis[u]=mindis+1;
gap[dis[u]]++;
u=pre[u];
}
return ans;
}
}sap;
int p[5050];
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;++i) scanf("%d",p+i);
ll sum = 0;
sap.init();
for(int i=1;i<=m;++i){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
sap.add(n+m+1,n+i,c);
sap.add(n+i,a,inf);
sap.add(n+i,b,inf);
sum+=c;
}
for(int i=1;i<=n;++i)
sap.add(i,n+m+2,p[i]);
ll mf = sap.max_flow(n+m+1,n+m+2,n+m+2);
printf("%I64d\n",sum-mf);
}
return 0;
}
HDU 3879 Base Station(最大权闭合子图)的更多相关文章
- HDU 3879 Base Station(最大权闭合子图)
将第i个用户和他需要的基站连边,转化成求二分图的最大权闭合子图. 答案=正权点之和-最小割. # include <cstdio> # include <cstring> # ...
- hdu 3879 Base Station 最大权闭合图
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 A famous mobile communication company is plannin ...
- hdu3879 Base Station 最大权闭合子图 边权有正有负
/** 题目:hdu3879 Base Station 最大权闭合子图 边权有正有负 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 题意:给出n个 ...
- HDU 3879 Base Station
Base Station Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original I ...
- hdu 5772 String problem 最大权闭合子图
String problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5772 Description This is a simple pro ...
- hdu 3917 Road constructions 最大权闭合子图
样例说明: n(城市数目) m(工程队数目) 每个工程队上交的税收 val[i] k(k个工程) xi yi ci costi , 工程队ci承包由xi到yi,政府的补贴为costi 注意 ...
- HDU 5855 Less Time, More profit 最大权闭合子图
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5855 Less Time, More profit Time Limit: 2000/1000 MS ...
- HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4971 Description There's a company with several ...
- HDU5855 Less Time, More profit(最大权闭合子图)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5855 Description The city planners plan to build ...
随机推荐
- [CareerCup] 18.1 Add Two Numbers 两数相加
18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators. 这道题让我 ...
- LintCode-Longest Increasing Subsequence
Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return ...
- 马后炮之12306抢票工具(四)--抢票Demo,2014年1月9日终结版
时隔一年多,终于朋友的忽悠下吧抢票Demo的最后一步完善了,与2014年1月9日成功生成车票. Demo仅经过自己测试,并未在高峰期进行测试,代码质量很差,因为赶工,套用去年模板并未使用设计模式. 代 ...
- Linq to Xml读取复杂xml(带命名空间)
前言:xml的操作方式有多种,但要论使用频繁程度,博主用得最多的还是Linq to xml的方式,觉得它使用起来很方便,就用那么几个方法就能完成简单xml的读写.之前做的一个项目有一个很变态的需求:C ...
- Git 命令速查图
- mysql返回最后一列数据
获取MySQL的表中每个userid最后一条记录的方法,并且针对userid不唯一的情况,需要的朋友可以参考下 表结构 CREATE TABLE `t1` ( `userid` int(11) DEF ...
- bzoj4559: [JLoi2016]成绩比较
感谢丁爷爷教我做这个题的后半部分. 首先,运用一发容斥原理,求出所有人与B神每门课分数相对关系的不同方案数. 这个似乎大(wo)家(lan)都(de)会(hui)了(yi),我就不说了,详见代码里的f ...
- 常见linux命令释义(第八天)—— Bash Shell 的操作环境
换了新公司,公司的领导很不错.自己感受比较多的地方是,自己的工作效率明显比以前高了.以前会对频繁变动的需求十分不耐烦,现在接到需求后会仔细的思考,进行整体构建.即使以后需求有变动,也能够比较轻易的在原 ...
- bzoj4571: [Scoi2016]美味
4571: [Scoi2016]美味 Time Limit: 30 Sec Memory Limit: 256 MB Submit: 275 Solved: 141 [Submit][Status][ ...
- mysql关联表的复制
1. 复制被参照的表: CREATE TABLE clone_product_1 LIKE product_1; INSERT INTO clone_product_1 SELECT * FROM p ...