POJ2125 Destroying The Graph
题目链接:ヾ(≧∇≦*)ゝ
大致题意:
给出一个有向图D=(V,E).对于每个点U,定义两种操作a(u),b(u)
操作a(u):删除点U的所有出边,即属于E,操作花费为Ca(u).
操作b(u):删除点U的所有入边,即属于E,操作花费为Cb(u).
求将原图的边集的边全部删除的最小代价,总操作数和具体操作
Solution:
第一问很简单,首先,对于每一个点,把它分成出点和入点。
把每个点的出点与S相连,入点与T相连。边容量分别为删除该点所有入边和出边的花费。
然后对于每条边 a -> b,就把a的出点与b的入点连一条容量为inf的边。
根据最大流=最小割,跑一遍dinic就能得到答案了。
对于第二、三问,我们分别统计a操作和b操作。
我们先对剩余网络进行bfs(),把能够扫到的点都标记为1,不能的标记为0。
对于一个点u,如果要使用a(u),那么显然,需要至少存在一个点v,满足u -> v &&
vis[u]vis[v]0。
而对于点u,如果要使用b(u),只需要满足vis[u]==1就行了。
为了防止重复输出,在定义一个apr数组记录每个数是否加入到答案中就行了。
详见代码
Code:
#include<queue>
#include<ctype.h>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1001
#define M 20001
#define inf 1926081700
using namespace std;
int S,T,head[N];
int n,m,cnt=1;
int ru[N],cu[N];
int ans,vis[N],apr[N];
int t1,t2,fst[N],sec[N];
struct Edge{int nxt,to,val;}edge[M];
void ins(int x,int y,int z){
edge[++cnt].nxt=head[x];
edge[cnt].to=y;edge[cnt].val=z;
head[x]=cnt;
}
namespace Network_Flow{
queue<int> q;
int dep[N];
int bfs(){
memset(dep,0,sizeof(dep));
q.push(S);dep[S]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to,v=edge[i].val;
if(!dep[y]&&v){
q.push(y);
dep[y]=dep[x]+1;
}
}
}
return dep[T];
}
int dfs(int x,int rest){
if(x==T||rest<=0) return rest;
int flow=0;
for(int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to,v=edge[i].val;
if(dep[y]==dep[x]+1&&v){
int now=dfs(y,min(rest,v));
edge[i].val-=now;
edge[i^1].val+=now;
flow+=now;rest-=now;
if(!rest) break;
}
}
return flow;
}
int dinic(){
int maxflow=0;
while(bfs()) maxflow+=dfs(S,inf);
return maxflow;
}
}
void getspj(){
queue<int> s;
s.push(S);vis[S]=1;
while(!s.empty()){
int x=s.front();s.pop();
for(int i=head[x];i;i=edge[i].nxt)
if(!vis[edge[i].to]&&edge[i].val){
s.push(edge[i].to);
vis[edge[i].to]=1;
}
}
apr[S]=apr[T]=1;
}
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int main(){
n=read(),m=read();
S=n*2+1,T=S+1;
for(int i=1;i<=n;i++) ru[i]=read();
for(int i=1;i<=n;i++) cu[i]=read();
for(int i=1;i<=n;i++){
ins(S,i,cu[i]);ins(i,S,0);
ins(i+n,T,ru[i]);ins(T,i+n,0);
}
for(int x,y,i=1;i<=m;i++){
x=read(),y=read();
ins(x,n+y,inf);
ins(n+y,x,0);
}
using namespace Network_Flow;
printf("%d\n",dinic());getspj();
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=edge[j].nxt){
int y=edge[j].to;
if(!vis[i]&&!vis[y]&&!apr[i]){
sec[++t2]=i;
ans++;apr[i]=1;
}
if(!apr[y]&&vis[y]){
fst[++t1]=y%n;
if(!fst[t1]) fst[t1]=n;
ans++;apr[y]=1;
}
}
printf("%d\n",ans);
for(int i=1;i<=t1;i++) printf("%d +\n",fst[i]);
for(int i=1;i<=t2;i++) printf("%d -\n",sec[i]);
return 0;
}
POJ2125 Destroying The Graph的更多相关文章
- POJ2125 Destroying The Graph (最小点权覆盖集)(网络流最小割)
Destroying The Graph Time Limit: 2000MS Memo ...
- POJ2125 Destroying The Graph(二分图最小点权覆盖集)
最小点权覆盖就是,对于有点权的有向图,选出权值和最少的点的集合覆盖所有的边. 解二分图最小点权覆盖集可以用最小割: vs-X-Y-vt这样连边,vs和X部点的连边容量为X部点的权值,Y部和vt连边容量 ...
- 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
网络流/二分图最小点权覆盖 果然还是应该先看下胡伯涛的论文…… orz proverbs 题意: N个点M条边的有向图,给出如下两种操作.删除点i的所有出边,代价是Ai.删除点j的所有入边,代价是Bj ...
- 图论(网络流,二分图最小点权覆盖):POJ 2125 Destroying The Graph
Destroying The Graph Description Alice and Bob play the following game. First, Alice draws some di ...
- POJ 2125 Destroying The Graph [最小割 打印方案]
Destroying The Graph Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8311 Accepted: 2 ...
- poj 2125 Destroying The Graph (最小点权覆盖)
Destroying The Graph http://poj.org/problem?id=2125 Time Limit: 2000MS Memory Limit: 65536K ...
- AC日记——Destroying The Graph poj 2125
Destroying The Graph Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8356 Accepted: 2 ...
随机推荐
- 20155227《网络对抗》Exp4 恶意代码分析
20155227<网络对抗>Exp4 恶意代码分析 实践目标 1.是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分 ...
- linux下使用软连接之案例二
在笔者的上一篇文章介绍过怎么通过linux的软连接在不修改上传代码的情况下,将上传到项目路径下的图片改为上传到项目外面,防止重新部署后图片被删除了.同时还可以直接通过类似访问静态资源的方 ...
- [BZOJ1135][POI2009]Lyz[霍尔定理+线段树]
题意 题目链接 分析 这个二分图匹配模型直接建图的复杂度太高,考虑霍尔定理. 对于某些人组成的区间,我们只需要考虑他们的并是一段连续的区间的集合.更进一步地,我们考虑的人一定是连续的. 假设我们考虑的 ...
- [51Nod1238]最小公倍数之和 V3[杜教筛]
题意 给定 \(n\) ,求 \(\sum_{i=1}^n \sum_{j=1}^n lcm(i,j)\). \(n\leq 10^{10}\) 分析 推式子 \[\begin{aligned} an ...
- [Luogu5048] [Ynoi2019模拟赛]Yuno loves sqrt technology III[分块]
题意 长为 \(n\) 的序列,询问区间众数,强制在线. \(n\leq 5\times 10^5\). 分析 考虑分块,暴力统计出整块到整块之间的众数次数. 然后答案还可能出现在两边的两个独立的块中 ...
- 把Excel的数据导入到数据库
将Excel作为数据源,将数据导入数据库,是SSIS的一个简单的应用,下图是示例Excel,数据列是code和name 第一部分,Excel中的数据类型是数值类型 1,使用SSDT创建一个packag ...
- 使用Python实时获取cmd的输出
最近发现一个问题,一个小伙儿写的console程序不够健壮,监听SOCKET的时候容易崩,造成程序的整体奔溃,无奈他没有找到问题的解决办法,一直解决不了,可是这又是一个监控程序,还是比较要紧的,又必须 ...
- Linux 僵尸进程
Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态.例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止.如果子进 ...
- 学习git 新手。这个写的不错
转自:https://www.cnblogs.com/wupeiqi/p/7295372.html 版本控制 说到版本控制,脑海里总会浮现大学毕业是写毕业论文的场景,你电脑上的毕业论文一定出现过这番景 ...
- Unity导入模型出现 (Avatar Rig Configuration mis-match. Bone length in configuration does not match position in animation)?
昨天遇到这两个模型导入的问题,查了一下资料,自己摸索了一下解决方法..总结一下~ 出现的原因:(问题1)Warning 当模型文件导入以后并且设置Animation Type是Generic的时候,动 ...