POJ2125 Destroying The Graph(二分图最小点权覆盖集)
最小点权覆盖就是,对于有点权的有向图,选出权值和最少的点的集合覆盖所有的边。
解二分图最小点权覆盖集可以用最小割:
- vs-X-Y-vt这样连边,vs和X部点的连边容量为X部点的权值,Y部和vt连边容量为Y部点的权值,X和Y是原二分图中的边容量为INF。
这一题建二分图是这样的:把原图中的点拆成两个点分别作二分图的X部和Y部,一个入点u+一个出点u-,权值就是题目给的那两个;原图中每条有向弧<u,v>变成二分图的边(u-,v+)。
然后就是建立容量网络,利用最小割求出这个二分图的最小点权覆盖集。
最后,最小割的割边集就对应着一个方案的解。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 222
#define MAXM 222*222*2 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-) continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=INF;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==) break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
} bool S[MAXN];
void dfs(int u){
S[u]=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && !S[v]) dfs(v);
}
}
int main(){
int n,m,a,b;
while(~scanf("%d%d",&n,&m)){
memset(head,-,sizeof(head));
vs=; vt=n<<|; NV=vt+; NE=;
for(int i=; i<=n; ++i){
scanf("%d",&a);
addEdge(vs,i,a);
}
for(int i=; i<=n; ++i){
scanf("%d",&a);
addEdge(i+n,vt,a);
}
while(m--){
scanf("%d%d",&a,&b);
addEdge(b,a+n,INF);
}
printf("%d\n",ISAP());
memset(S,,sizeof(S));
dfs(vs);
int res[MAXN],resn=;
for(int i=; i<NE; i+=){
if(edge[i].cap==edge[i].flow && S[edge[i^].v] && !S[edge[i].v]){
if(edge[i^].v==vs) res[resn++]=edge[i].v;
else if(edge[i].v==vt) res[resn++]=edge[i^].v;
}
}
printf("%d\n",resn);
for(int i=; i<resn; ++i){
if(res[i]<=n) printf("%d +\n",res[i]);
else printf("%d -\n",res[i]-n);
}
}
return ;
}
POJ2125 Destroying The Graph(二分图最小点权覆盖集)的更多相关文章
- POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)
题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...
- POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割
思路来源:http://blog.csdn.net/lenleaves/article/details/7873441 求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边, 只要用最终的剩余网络 ...
- POJ 2125 Destroying the Graph 二分图最小点权覆盖
Destroying The Graph Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8198 Accepted: 2 ...
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
POJ2125 题意简述:给定一个有向图,要通过某些操作删除所有的边,每一次操作可以选择任意一个节点删除由其出发的所有边或者通向它的所有边,两个方向有不同的权值.问最小权值和的解决方案,要输出操作. ...
- poj 2125 Destroying The Graph (最小点权覆盖)
Destroying The Graph http://poj.org/problem?id=2125 Time Limit: 2000MS Memory Limit: 65536K ...
- 最小点权覆盖集&最大点权独立集
最小点权覆盖集 二分图最小点权覆盖集解决的是这样一个问题: 在二分图中,对于每条边,两个端点至少选一个,求所选取的点最小权值和. 方法: 1.先对图二分染色,对于每条边两端点的颜色不同 2.然后建立源 ...
- POJ2125 Destroying The Graph (最小点权覆盖集)(网络流最小割)
Destroying The Graph Time Limit: 2000MS Memo ...
- hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...
- POJ 2125 最小点权覆盖集(输出方案)
题意:给一个图(有自回路,重边),要去掉所有边,规则:对某个点,可以有2种操作:去掉进入该点 的所有边,也可以去掉出该点所有边,(第一种代价为w+,第二种代价为w-).求最小代价去除所有边. 己思:点 ...
随机推荐
- CSS3实现二十多种基本图形
CSS3可以实现很多漂亮的图形,我收集了32种图形,在下面列出.直接用CSS3画出这些图形,要比贴图性能更好,体验更加,是一种非常好的网页美观方式. 这32种图形分别为圆形,椭圆形,三角形,倒三角形, ...
- [Effective JavaScript 笔记] 第11条:熟练掌握闭包
理解闭包三个基本的事实 第一个事实:js允许你引用在当前函数以外定义的变量. function makeSandwich(){ var magicIngredient=”peanut butter”; ...
- Python Django 的 django templatedoesnotexist
django 1.8版本的解决方案 在 setting.py 这个文件里 TEMPLATES = [ ...... #原来的 #'DIRS': [ ], // 这个 列表里添加 template路 ...
- php友好格式化时间
php格式化时间显示 function toTime($time) {//$time必须为时间戳 $rtime = date("Y-m-d H:i",$time); $htime ...
- 又一款linux提权辅助工具
又一款linux提权辅助工具 – Linux_Exploit_Suggester 2013-09-06 10:34 1455人阅读 评论(0) 收藏 举报 https://github.com/Pen ...
- ASP.NET - 视图状态概述
本文转载自dodream 视图状态是 ASP.NET 页框架用于在往返过程之间保留页和控件值的方法.在呈现页的 HTML 标记时,必须在回发过程中保留的页和值的当前状态将被序列化为Base64 编码字 ...
- Android 转载一篇.9图片详解文章
感谢作者,原文链接为 http://blog.csdn.net/ouyang_peng/article/details/9242889
- iOS 用protocol 和 用继承小体会
最近写程序时,2个类都有相同的函数,又因为在用oc,所以就用了protocol来实现.后来发现其实这2个类除了相同的函数,还需要一些相同的变量,当初用继承的话会更简单.
- MPlayer-ww 增加边看边剪切功能+生成高质量GIF功能
http://pan.baidu.com/s/1eQm5a74 下载FFmpeg palettegen paletteuse documentation 需要下载 FFmpeg2.6 以上 并FFmp ...
- JavaEE面试题库
Java EE软件工程师 认证考试 面试题大全 目 录 第一部分 HTML/CSS/JavaScript 1 1. HTML含义和版本变化... 1 2. ...