Destroying The Graph
Time Limit: 2000MS   Memory Limit: 65536K
         

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 +
题目大意:
n个点m条边的有向图
需要移走这张图里所有的边
每次可以选择移走点i的所有入边或所有出边
每步操作都有对应的代价
求最小代价移走所有的边
注:边有自环和平行边 最小点权覆盖集
=最小割
拆点
源点向每个点连一条流量为outgoing pay的边
每个点向汇点连一条流量为incoming pay的边
原图中的边i,j,由i向拆出的j连inf边
跑最小割
方案的输出:
从源点遍历残量网络,边还有流量就遍历,记录所有遍历到的点
原本就有的点,如果没有被遍历到,就说明它被割了
拆出的点,如果被遍历到,说明它被割了
#include<cstdio>
#include<queue>
using namespace std;
int n,m,tot=,ans;
int front[],to[],nextt[],cap[];
int lev[],cur[];
int src,decc;
bool g[];
queue<int>q;
void add(int u,int v,int w)
{
to[++tot]=v;nextt[tot]=front[u];front[u]=tot;cap[tot]=w;
to[++tot]=u;nextt[tot]=front[v];front[v]=tot;cap[tot]=;
}
bool bfs()
{
for(int i=;i<=decc;i++) {lev[i]=-;cur[i]=front[i];}
while(!q.empty()) q.pop();
q.push(src);lev[src]=;
while(!q.empty())
{
int now=q.front();q.pop();
for(int i=front[now];i;i=nextt[i])
{
int t=to[i];
if(cap[i]>&&lev[t]==-)
{
lev[t]=lev[now]+;
q.push(t);
if(t==decc) return true;
}
}
}
return false;
}
int dinic(int now,int flow)
{
if(now==decc) return flow;
int rest=,delta;
for(int & i=cur[now];i;i=nextt[i])
{
int t=to[i];
if(lev[t]>lev[now]&&cap[i]>)
{
delta=dinic(t,min(flow-rest,cap[i]));
if(delta)
{
cap[i]-=delta;cap[i^]+=delta;
rest+=delta;if(rest==flow) break;
}
}
}
if(rest!=flow) lev[now]=-;
return rest;
}
void cut(int now)
{
g[now]=true;
for(int i=front[now];i;i=nextt[i])
{
if(cap[i]==||g[to[i]]) continue;
cut(to[i]);
}
}
int main()
{
scanf("%d%d",&n,&m);
decc=n+<<;
int x,y;
for(int i=;i<=n;i++)
{
scanf("%d",&x);
add(i<<|,decc,x);
}
for(int i=;i<=n;i++)
{
scanf("%d",&x);
add(src,i<<,x);
}
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x<<,y<<|,2e9);
}
while(bfs()) ans+=dinic(src,2e9);
printf("%d\n",ans);
int sum=;
cut(src);
for(int i=;i<=n;i++)
{
if(g[i<<|]) sum++;
if(!g[i<<]) sum++;
}
printf("%d\n",sum);
for(int i=;i<=n;i++)
{
if(!g[i<<]) printf("%d -\n",i);
if(g[i<<|]) printf("%d +\n",i); }
}

错误:

1、

应该是

源点向每个点连一条流量为outgoing pay的边

每个点向汇点连一条流量为incoming pay的边

连反了

与源点相连的点,连出去的边是点打出的,所以源点与点之间的边控制的是出边的流量

汇点同理

2、方案输出方法错误

错误方法:

在残量网络中,如果与源点相连的边流量为0,说明这个点被割了

如果汇点连出去的边的流量 为这条边指 向的点的原流量,说明这个点被割了

前半部分是正确的,但后半部分是错的

因为跑最大流过程中,增光路上所有边流量都减,

比如有一条边由1指向2,所有花费都是1

跑完最大流后,源点——1 残量为0

2——汇点 残量为0

最终判断的是割掉2个点,但实际割其中一个就行

/*for(int i=front[src];i;i=nextt[i])
{
if(cap[i]==0)
{
sum++;
a[sum][0]=to[i]/2;a[sum][1]='+';
}
}
for(int i=front[decc];i;i=nextt[i])
{
if(cap[i]==out[to[i]/2])
{
sum++;
a[sum][0]=to[i]/2;a[sum][1]='-';
}
}*/

错误代码

3、题目中说有自环,做的时候把它特判去掉了,错

poj 2125 Destroying The Graph (最小点权覆盖)的更多相关文章

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

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

  2. POJ2125 Destroying The Graph (最小点权覆盖集)(网络流最小割)

                                                          Destroying The Graph Time Limit: 2000MS   Memo ...

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

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

  4. poj 2125 Destroying The Graph 最小割+方案输出

    构图思路: 1.将所有顶点v拆成两个点, v1,v2 2.源点S与v1连边,容量为 W- 3.v2与汇点连边,容量为 W+ 4.对图中原边( a, b ), 连边 (a1,b2),容量为正无穷大 则该 ...

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

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

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

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

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

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

  8. POJ 3308 Paratroopers (对数转换+最小点权覆盖)

    题意 敌人侵略r*c的地图.为了消灭敌人,可以在某一行或者某一列安置超级大炮.每一个大炮可以瞬间消灭这一行(或者列)的敌人.安装消灭第i行的大炮消费是ri.安装消灭第j行的大炮消费是ci现在有n个敌人 ...

  9. poj 3308 Paratroopers(二分图最小点权覆盖)

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

随机推荐

  1. Tensorflow踩坑之tf.nn.bidirectional_dynamic_rnn()报错 “ValueError: None values not supported.”

    详细解决方法见链接:https://stackoverflow.com/questions/39808336/tensorflow-bidirectional-dynamic-rnn-none-val ...

  2. C++操作mysql方法总结(2)

    C++通过ODBC和通过MFC ODBC操作mysql的两种方式 使用vs2013和64位的msql 5.6.16进行操作 项目中使用的数据库名和表数据请参考C++操作mysql方法总结(1)中的介绍 ...

  3. 关于jsonp知识的理解

    jsonp 之前知道是用来解决ajax跨域的问题,但是其本质的原理,还是不清楚. 所以看了一下. js的script 的src里面的连接是可以跨域的,所以可以通过她来实现跨域资源获取. 但是也需要后端 ...

  4. PAT 1072 开学寄语

    https://pintia.cn/problem-sets/994805260223102976/problems/994805263964422144 1072 开学寄语(20 分)提问 下图是上 ...

  5. 【硬件】- 英特尔CPU命名规则

    前言 一款Intel CPU的命名,一般由5个部分组成:品牌,品牌标识符,Gen标识,SKU数值,产品线后缀. 以下图为例: 品牌 英特尔旗下处理器有许多子品牌,包括我们熟悉的凌动(ATOM).赛扬( ...

  6. [转帖]华为Hi 1620 等ARM 服务器版本CPU信息.

    华为ARM服务器恐依赖党政输血续命 一旦制裁立马休克 http://www.sohu.com/a/240833070_99934330 几年前,ARM服务器被业界炒的火热,AMD.高通.Marvell ...

  7. 半夜思考之查漏补缺 , Spring 中 Bean 之间的依赖问题

    每次看书都会发现自己的不足 . 当一个 singten 的 Bean 依赖一个 prototype 的 Bean 时 , 如果不加注意 , 会发生一些奇怪的事情 , prototype 变为了 sin ...

  8. Hystrix 容错处理

    目录 雪崩效应 容错的基本思想 什么是Hystrix 简单使用 消费端使用Hystrix 注解开启 改造消费方法 @HystrixCommand 详细配置 Hystrix线程隔离策略与传播上下文 Hy ...

  9. java中new两个对象,在堆中开辟几个对象空间

    内存堆中有两个对象,两个对象里都有独立的变量.p1 p2指向的不是同一个内存空间. 也可以这样描述引用p1,p2指向两个不同的对象.

  10. python 求两个时间差

    def timeInterval(self): today = datetime.date.today() print today modifiedTime = os.stat(filename).s ...