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. java异常处理及自定义异常的使用

    1. 异常介绍 异常机制可以提高程序的健壮性和容错性. Throwable:Throwable是java语言所有错误或异常的超类. 有两个子类Error和Exception. 1.1 编译期异常 编译 ...

  2. 20_集合_第20天(Map、可变参数、Collections)_讲义

    今日内容介绍 1.Map接口 2.模拟斗地主洗牌发牌 01Map集合概述 A:Map集合概述: 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式 ...

  3. 在dell服务器上装windows server 2012详细解析

    壹: 首先确定磁盘阵列的问题,在dell服务器开机后按住 Ctrl+R 或者 F2 会展开虚拟磁盘创建菜单 详细步骤可以查看:https://jingyan.baidu.com/article/915 ...

  4. 微信小程序wx:for和wx:for-item的正确用法

    wx:for="{{list}}"用来循环数组,而list即为数组名wx:for-item="items" 即用来定义一个循环过程中每个元素的变量的 如果是一维 ...

  5. 关于.net服务启动注册到zookeeper,但是注册节点20分钟自动消失解决办法

        ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,作用简单描述就是相当于一个中介,服务提供者将服务注册到zk,服务调用者直接从zk获取,zk的作用就是协调     最近碰到公 ...

  6. Android事件分派机制

    最近一直在学习Android里面的事件分派机制,感觉很奇妙,看了很多博客和分析,才在脑子里形成了一个模糊的概念,对事件分派有了一定的认识. 于是,我画了一个图来简单明了的表述Android中事件的分派 ...

  7. 动态生成lookup字段

    var  i: Integer;begin  //ADOQuery已打开   //在数据集打开的情况下新增加一个字段  with Self.ADOQuery1 do  begin    TDataSe ...

  8. 原生Ajax函数

    前言 在日常工作中,我经常使用Jquery的Ajax来获取接口数据.这几天有一个的官网要制作,由于网站比较小,有一些与服务器通信的接口处理,并没有涉及到复杂的交互功能.为了可以减少加载Jquery库的 ...

  9. Netty简单使用

    目录 丢弃服务器 DiscardServerHandler DiscardServer 测试 应答服务器 时间服务器 TimeServerHandler TimeClient TimeClientHa ...

  10. SGU326_Perspective

    NBA打比赛.所有的比赛被分为多个团队.有的比赛是团内的,有的是与团外的队伍打的. 给出团内每个队伍已得分,以及总共有多少场比赛,还有团内所有队伍之间有多少场比赛? 问1队是否可能是分数最高的一个队伍 ...