Destroying The Graph

Description

Alice and Bob play the following game. First, Alice draws some directed graph with N vertices and M arcs. After that Bob tries to destroy it. In a move he may take any vertex of the graph and remove either all arcs incoming into this vertex, or all arcs outgoing from this vertex.
Alice assigns two costs to each vertex: Wi+ and Wi-. If Bob removes all arcs incoming into the i-th vertex he pays Wi+ dollars to Alice, and if he removes outgoing arcs he pays Wi- dollars.

Find out what minimal sum Bob needs to remove all arcs from the graph.

Input

Input
file describes the graph Alice has drawn. The first line of the input
file contains N and M (1 <= N <= 100, 1 <= M <= 5000). The
second line contains N integer numbers specifying Wi+. The third line defines Wi- in a similar way. All costs are positive and do not exceed 106
. Each of the following M lines contains two integers describing the
corresponding arc of the graph. Graph may contain loops and parallel
arcs.

Output

On
the first line of the output file print W --- the minimal sum Bob must
have to remove all arcs from the graph. On the second line print K ---
the number of moves Bob needs to do it. After that print K lines that
describe Bob's moves. Each line must first contain the number of the
vertex and then '+' or '-' character, separated by one space. Character
'+' means that Bob removes all arcs incoming into the specified vertex
and '-' that Bob removes all arcs outgoing from the specified vertex.

Sample Input

```3 6
1 2 3
4 2 1
1 2
1 1
3 2
1 2
3 1
2 3
```

Sample Output

```5
3
1 +
2 -
2 +

```
``` #include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn=;
const int maxm=;
const int INF=;
int cnt,tot,fir[maxn],fron[maxn],dis[maxn];
int to[maxm],nxt[maxm],gap[maxn],path[maxn];
int cap[maxm];queue<int>q;

struct Max_Flow{
void Init(int tot_=){
tot=tot_;cnt=;
memset(fir,,sizeof(fir));
memset(dis,,sizeof(dis));
memset(gap,,sizeof(gap));
}

nxt[++cnt]=fir[a];
fir[a]=cnt;
cap[cnt]=c;
to[cnt]=b;
}

}

bool BFS(int s,int t){
dis[t]=;q.push(t);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=fir[x];i;i=nxt[i])
if(!dis[to[i]]){
dis[to[i]]=dis[x]+;
q.push(to[i]);
}
}
return dis[s];
}

int Aug(int s,int t,int &p){
int f=INF;
while(p!=s){
f=min(f,cap[path[p]]);
p=to[path[p]^];
}p=t;
while(p!=s){
cap[path[p]]-=f;
cap[path[p]^]+=f;
p=to[path[p]^];
}
return f;
}

int ISAP(int s,int t){
if(!BFS(s,t))return ;
for(int i=s;i<=t;i++)fron[i]=fir[i];
for(int i=s;i<=t;i++)gap[dis[i]]+=;
int p=s,ret=;
while(dis[s]<=tot){
if(p==t)ret+=Aug(s,t,p);

for(int &i=fron[p];i;i=nxt[i])
if(cap[i]&&dis[p]==dis[to[i]]+){
path[p=to[i]]=i;
break;
}

if(!fron[p]){
if(--gap[dis[p]]==)
break;
int Min=tot;
for(int i=fir[p];i;i=nxt[i])
if(cap[i])Min=min(Min,dis[to[i]]);
gap[dis[p]=Min+]+=;fron[p]=fir[p];
if(p!=s)p=to[path[p]^];
}
}
return ret;
}
}isap;

int n,m,top;
int tag[maxn],st[maxn];
void DFS(int x){
tag[x]=;
for(int i=fir[x];i;i=nxt[i])
if(cap[i]&&!tag[to[i]])DFS(to[i]);
}

int main(){
scanf("%d%d",&n,&m);
int s=,t=*n+;
isap.Init(t+);
for(int i=,v;i<=n;i++){
scanf("%d",&v);
}
for(int i=,v;i<=n;i++){
scanf("%d",&v);
}
for(int i=,a,b;i<=m;i++){
scanf("%d%d",&a,&b);
}

printf("%d\n",isap.ISAP(s,t));
DFS();
for(int i=;i<=n;i++){
if(!tag[i])
st[++top]=i;
if(tag[i+n])
st[++top]=i+n;
}
printf("%d\n",top);
for(int i=;i<=top;i++){
if(st[i]<=n)
printf("%d +\n",st[i]);
else
printf("%d -\n",st[i]-n);
}
return ;
}```

## 图论（网络流，二分图最小点权覆盖）：POJ 2125 Destroying The Graph的更多相关文章

1. POJ 2125 Destroying the Graph 二分图最小点权覆盖

Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8198   Accepted: 2 ...

2. POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)

题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...

3. POJ 2125 Destroying The Graph 二分图 最小点权覆盖

POJ2125 题意简述:给定一个有向图,要通过某些操作删除所有的边,每一次操作可以选择任意一个节点删除由其出发的所有边或者通向它的所有边,两个方向有不同的权值.问最小权值和的解决方案,要输出操作. ...

4. POJ2125 Destroying The Graph（二分图最小点权覆盖集）

最小点权覆盖就是,对于有点权的有向图,选出权值和最少的点的集合覆盖所有的边. 解二分图最小点权覆盖集可以用最小割: vs-X-Y-vt这样连边,vs和X部点的连边容量为X部点的权值,Y部和vt连边容量 ...

5. poj 3308 Paratroopers（二分图最小点权覆盖）

Paratroopers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8954   Accepted: 2702 Desc ...

6. POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割

思路来源:http://blog.csdn.net/lenleaves/article/details/7873441 求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边, 只要用最终的剩余网络 ...

7. poj 2125 Destroying The Graph （最小点权覆盖）

Destroying The Graph http://poj.org/problem?id=2125 Time Limit: 2000MS   Memory Limit: 65536K       ...

8. POJ - 2125 Destroying The Graph (最小点权覆盖)

题意:给一张图,现在要删去所有的边,删去一个点的所有入边和所有出边都有其对应\(W_{i+}\)和\(W_{i-}\).求删去该图的最小花费,并输出解 分析:简而言之就是用最小权值的点集去覆盖所有的边 ...

9. POJ3308 Paratroopers（最小割/二分图最小点权覆盖）

把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖. 此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运 ...

10. POJ 2125 Destroying The Graph [最小割 打印方案]

Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8311   Accepted: 2 ...

## 随机推荐

1. <canvas>drawImage()方法无法显示图片

在书上看到用<canvas>绘制图像就动手试试,刚开始,我的代码是这样的: <!DOCTYPE html> <html> <head> <meta ...

3. r语言之生成随机序列，随机数生成函数及用法

(1)生成正态分布随机数: rnorm(n,mean,sd)     其中,n表示生成的随机数个数,mean表示正态分布均值,sd表示正态分布标准差 > rnorm(5,0,2)[1] -5.3 ...

4. json字符串和对象的相互转化

json在代码中是经常用到的,在此总结一下json字符串和对象及数组之间的相互转化: 1.javascript函数方式: <1> JSON.stringify :把一个对象转换成json字 ...

5. 描述进程的PCB

body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

6. reactive stream: 响应式编程

既然 Reactive Stream 和 Java 8 引入的 Stream 都叫做流,它们之间有什么关系呢?有一点关系,Java 8 的 Stream 主要关注在流的过滤,映射,合并,而  Reac ...

7. Ubuntu14.04配置jdk1.8.0_25，可切换版本