构图思路:

1.将所有顶点v拆成两个点, v1,v2

2.源点S与v1连边,容量为 W-

3.v2与汇点连边,容量为 W+

4.对图中原边( a, b ), 连边 (a1,b2),容量为正无穷大

则该图的最小割(最大流)即为最小花费。

简单证明: 根据ST割集的定义,将顶点分成两个点集。所以对于原图中的边(a,b),转换成 S->a1->b2->T. 则此时路径必定存在

一条割边,因为a1->b2为无穷大,所以割边必定是 S->a1 or b2->T,  若为前者则意味着删除a顶点的W-,后者则是b顶点的W+.

所以该图最小割即为最小花费。

计算方案: 对于构图后跑一次最大流,然后对于残留网络进行处理,首先从源点S出发,标记所有能访问到的顶点,这些顶点即为S割点集中

的顶点。 其他则为T集合中顶点, 然后从所有边中筛选出( A属于S,B属于T,且(A,B)容量为0 )的边,即为割边。因为我们的W+/W-边都只有一条,

且都分开了。比较容易处理。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<vector>
#include<algorithm>
using namespace std; const int MAXN = ;
const int MAXM = ;
const int inf = 0x3f3f3f3f;
int A[MAXN], B[MAXN];
struct Edge{
int u, v, f, nxt;
}edge[];
int head[MAXN], idx;
int n, m;
int S, T, N; void AddEdge(int u,int v,int f){
edge[idx].u = u, edge[idx].v = v, edge[idx].f = f;
edge[idx].nxt = head[u]; head[u] = idx++;
edge[idx].u = v, edge[idx].v = u, edge[idx].f = ;
edge[idx].nxt = head[v]; head[v] = idx++;
} int h[MAXN], vh[MAXN];
int dfs(int u,int flow){
if(u == T) return flow;
int tmp = h[u]+, sum = flow;
for(int i = head[u]; ~i; i = edge[i].nxt){
if( edge[i].f && (h[edge[i].v]+ == h[u]) ){
int p = dfs( edge[i].v, min(sum,edge[i].f));
edge[i].f-=p, edge[i^].f+=p, sum-=p;
if( sum== || h[S]==N ) return flow-sum;
}
}
for(int i = head[u]; ~i; i = edge[i].nxt)
if( edge[i].f ) tmp = min( tmp, h[edge[i].v] );
if( --vh[ h[u] ] == ) h[S] = N;
else ++vh[ h[u]=tmp+ ];
return flow-sum;
}
int sap(){
int maxflow = ;
memset(h,,sizeof(h));
memset(vh,,sizeof(vh));
vh[] = N;
while( h[S] < N ) maxflow += dfs( S, inf );
return maxflow;
} bool vis[MAXN];
int res[MAXM]; void DFS(int u ){
vis[u] = true;
for(int i = head[u]; ~i; i = edge[i].nxt ){
int v = edge[i].v;
if( !vis[v] && edge[i].f )
DFS( v );
}
}
void solve(){
int maxflow = sap();
printf("%d\n", maxflow );
memset( vis,,sizeof(vis));
DFS( S ); int cnt = ;
for(int i = ; i < idx; i += ){
int u = edge[i].u, v = edge[i].v;
if( vis[u] && !vis[v] && (edge[i].f == ) )
res[cnt++] = i;
}
printf("%d\n", cnt );
for(int i = ; i < cnt; i++ ){
int u = edge[ res[i] ].u, v = edge[ res[i] ].v;
if( u == S ) printf("%d -\n", v);
else printf("%d +\n", u-n );
}
} int main(){
while( scanf("%d%d",&n,&m) != EOF ){
S = , T = *n+, N = *n+; idx = ;
memset( head, -, sizeof(head)); for(int i = ; i <= n; i++ )
scanf("%d", &A[i]);
for(int i = ; i <= n; i++ )
scanf("%d", &B[i]);
int a, b;
for(int i = ; i < m; i++ ){
scanf("%d%d", &a,&b);
AddEdge( a, n+b, inf );
}
for(int i = ; i <= n; i++){
AddEdge( S, i, B[i] ); // - out
AddEdge( n+i, T, A[i] );// + in
}
solve();
}
return ;
}

poj 2125 Destroying The Graph 最小割+方案输出的更多相关文章

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

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

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

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

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

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

  4. poj 2125 Destroying The Graph (最小点权覆盖)

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

  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

    Destroying The Graph   Description Alice and Bob play the following game. First, Alice draws some di ...

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

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

  8. ●POJ 2125 Destroying The Graph

    题链: http://poj.org/problem?id=2125 题解: 最小割 + 输出割方案.建图:拆点,每个题拆为 i 和 i'分别表示其的入点和出点建立超源 S和超汇 T.S -> ...

  9. poj 3469 Dual Core CPU——最小割

    题目:http://poj.org/problem?id=3469 最小割裸题. 那个限制就是在 i.j 之间连双向边. 根据本题能引出网络流中二元关系的种种. 别忘了写 if ( x==n+1 ) ...

随机推荐

  1. convertView&setTag方法的一点理解

    前言 首先我们要知道setTag方法是干什么的,SDK解释为 Tags Unlike IDs, tags are not used to identify views. Tags are essent ...

  2. Ajax请求全局配置

    摘要: jQuery已经成为项目中最常见的js库,也是前端开发最喜欢使用的库.下面是在项目中封装了jQuery的Ajax,分享给大家. 代码: // ajax 请求参数 var ajaxSetting ...

  3. iOS 将Excel导入到SQLite3的过程

    1.打开Excel表格,另存为.csv文件 2.打开SQLite3,选择File -> Import -> other... 3.在弹出的文件选择框中选择步骤1保存的.cvs文件 4在弹出 ...

  4. 【GIS】postgres(postgis) --》nodejs+express --》geojson --》leaflet

    一.基本架构 1.数据存储层:PostgreSQL-9.2.13 + postgis_2_0_pg92 2.业务处理层:Nodejs + Express + PG驱动 3.前端展示层:Leaflet ...

  5. 【GIS】使用GDAL为Leaflet切图

    一.参考资料 https://commenthol.github.io/leaflet-rastercoords/ https://github.com/commenthol/gdal2tiles-l ...

  6. Ldap 漏洞

    0x00 Ldap安装 官网地址:https://www.userbooster.de/en/download/openldap-for-windows.aspx 在win2008上安装,一路Next ...

  7. Redis 操作有序集合数据

    Redis 操作有序集合数据: > zadd names "Tom" // zadd 用于往有序集合中添加元素,其中 1 在 Redis 中称为 score(分数),用来进行 ...

  8. Kafka controller重设计

    本文主要参考社区0.11版本Controller的重设计方案,试图给大家梳理一下Kafka controller这个组件在设计上的一些重要思考.众所周知,Kafka中有个关键组件叫controller ...

  9. Englis - 英文字母和音标

    英语学习基础基础是一切的根本 学习是一个长期积累知识的过程,正确掌握各科学习方法显得尤其重要!很多孩子学习成绩不好.记忆力不佳都是因为没有掌握正确的学习方法而造成的. 最基本的是:26个英文字母 48 ...

  10. JavaScript的数据类型---最全,最详细的数据类型,高级的工程师从数据类型开始

    一.基本数据类型 1.字符串数据类型     var hello="你好啊";     var hello='你好啊';示例:<script language="j ...