Destroying The Graph

构图思路:

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-边都只有一条,

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

  1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5 #include <algorithm>
6 #include <string>
7 #include <vector>
8 #include <set>
9 #include <map>
10 #include <stack>
11 #include <queue>
12 #include <sstream>
13 #include <iomanip>
14 using namespace std;
15 typedef long long LL;
16 const int INF = 0x4fffffff;
17 const double EXP = 1e-5;
18 const int MS = 2005;
19 const int SIZE = 100005;
20
21 struct edge
22 {
23 int v,c,f,other;
24 }e;
25
26 vector<edge> edges[MS]; // 邻接表
27 vector<int> level_edges[MS];
28 vector<int> ans;
29
30 int que[MS],level[MS],pre[MS],hash[MS],d[MS];
31 int s,t;
32
33 void add(int u,int v,int c)
34 {
35 e.v=v;
36 e.c=c;
37 e.f=0;
38 e.other=edges[v].size();
39 edges[u].push_back(e);
40
41 e.v=u; // reverse edge
42 e.c=0;
43 e.f=0;
44 e.other=edges[u].size()-1;
45 edges[v].push_back(e);
46 }
47
48 bool BFS() // bfs 构建层次网络
49 {
50 int head=0,tail=0,cur,i;
51 for(int i=s;i<=t;i++)
52 level_edges[i].clear();
53 memset(level,0xff,sizeof(level));
54 que[tail++]=s;
55 level[s]=0;
56 while(head<tail)
57 {
58 cur=que[head++];
59 for(i=0;i<edges[cur].size();i++)
60 {
61 e=edges[cur][i];
62 if(e.c>e.f)
63 {
64 if(level[e.v]==-1)
65 {
66 que[tail++]=e.v;
67 level[e.v]=level[cur]+1;
68 }
69 if(level[e.v]==level[cur]+1)
70 {
71 level_edges[cur].push_back(i);
72 }
73 }
74 }
75 }
76 if(level[t]!=-1)
77 return 1;
78 else
79 return 0;
80 }
81
82
83 int dinic()
84 {
85 int i,j,ans=0,len;
86 while(BFS())
87 {
88 memset(hash,0,sizeof(hash));
89 while(!hash[s])
90 {
91 d[s]=INF;
92 pre[s]=-1;
93 for(i=s;i!=t&&i!=-1;i=j)
94 {
95 len=level_edges[i].size();
96 while(len&&hash[ edges[i][level_edges[i][len-1]].v] )
97 {
98 level_edges[i].pop_back();
99 len--;
100 }
101 if(!len)
102 {
103 hash[i]=1;
104 j=pre[i];
105 continue;
106 }
107 j=edges[i][level_edges[i][len-1]].v;
108 pre[j]=i;
109 d[j]=min(d[i],edges[i][level_edges[i][len-1]].c-edges[i][level_edges[i][len-1]].f);
110 }
111 if(i==t)
112 {
113 ans+=d[t];
114 while(i!=s)
115 {
116 j=pre[i];
117 len=level_edges[j][level_edges[j].size()-1];
118 edges[j][len].f+=d[t];
119 if(edges[j][len].f==edges[j][len].c)
120 level_edges[j].pop_back();
121 edges[i][edges[j][len].other].f-=d[t];
122 i=j;
123 }
124 }
125 }
126 }
127 return ans;
128 }
129
130 void DFS(int u)
131 {
132 int i,k;
133 hash[u]=1;
134 for(i=0;i<edges[u].size();i++)
135 {
136 k=edges[u][i].v;
137 if(!hash[k]&&edges[u][i].c-edges[u][i].f>0)
138 DFS(k);
139 }
140 }
141
142 int main()
143 {
144 int n,m,i,j,k,N,tmp,answer;
145 while(scanf("%d%d",&n,&m)!=EOF)
146 {
147 N=2*n+1;
148 s=0;
149 t=N;
150 for(i=s;i<=t;i++)
151 edges[i].clear();
152 for(i=1;i<=n;i++)
153 {
154 scanf("%d",&tmp);
155 add(n+i,N,tmp);
156 }
157 for(i=1;i<=n;i++)
158 {
159 scanf("%d",&tmp);
160 add(0,i,tmp);
161 }
162 for(k=0;k<m;k++)
163 {
164 scanf("%d%d",&i,&j);
165 add(i,n+j,INF);
166 }
167 answer=dinic();
168 memset(hash,0,sizeof(hash));
169 DFS(0);
170 ans.clear();
171 for(i=1;i<=n;i++)
172 {
173 if(!hash[i])
174 ans.push_back(i);
175 if(hash[n+i])
176 ans.push_back(n+i);
177 }
178 printf("%d\n%d\n",answer,ans.size());
179 for(i=0;i<ans.size();i++)
180 {
181 if(ans[i]<=n)
182 printf("%d -\n",ans[i]);
183 else
184 printf("%d +\n",ans[i]-n);
185 }
186 }
187 return 0;
188 }

Destroying The Graph 最小点权集--最小割--最大流的更多相关文章

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

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

  2. POJ 3308 Paratroopers(最小点权覆盖)(对数乘转加)

    http://poj.org/problem?id=3308 r*c的地图 每一个大炮可以消灭一行一列的敌人 安装消灭第i行的大炮花费是ri 安装消灭第j行的大炮花费是ci 已知敌人坐标,同时消灭所有 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 解析CentOS 8上的Xrdp服务器安装

    解析CentOS 8上的Xrdp服务器安装   Linux系统技术交流QQ群(915246)验证问题答案:刘遄 导读 Xrdp 是 Microsoft 远程桌面协议 (RDP) 的开源实现,允许您以图 ...

  2. 详解Linux中的cat文本输出命令用法

    作系统 > LINUX >   详解Linux中的cat文本输出命令用法 Linux命令手册   发布时间:2016-01-14 14:14:35   作者:张映    我要评论   这篇 ...

  3. 企业案例-Mysql误删除用户表如何恢复

    1.不小心删除了mysql所有用户 mysql> delete from mysql.user where 1=1; Query OK, 5 rows affected (0.00 sec) # ...

  4. Socket编程——(转载)

    我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠so ...

  5. mysql基础之日志管理(查询日志、慢查询日志、错误日志、二进制日志、中继日志、事务日志)

    日志文件记录了MySQL数据库的各种类型的活动,MySQL数据库中常见的日志文件有 查询日志,慢查询日志,错误日志,二进制日志,中继日志 ,事务日志. 修改配置或者想要使配置永久生效需将内容写入配置文 ...

  6. MyBatis 环境搭建(四)

    MyBatis 引言 在回顾JDBC时,我们已经创建有 Java 工程,而且也已经导入 mysql 依赖包,这里就直接在原有工程上搭建MyBatis环境,以及使用MyBatis来实现之前用 JDBC ...

  7. 详解 WebRTC 高音质低延时的背后 — AGC(自动增益控制)

    前面我们介绍了 WebRTC 音频 3A 中的声学回声消除(AEC:Acoustic Echo Cancellation)的基本原理与优化方向,这一章我们接着聊另外一个 "A" - ...

  8. global nonlocal 闭包构建 变量名解析原则

  9. .NET6系列:C#10新功能预览

    系列目录     [已更新最新开发文章,点击查看详细] 2021年4月19日微软发布公告称将于今年夏季发布首款64位的 Visual Studio 2022,2021年5月20日又发布了 Visual ...

  10. Python+Selenium学习笔记11 - python官网的tutorial - 定义函数

    1 def f(a, L=[]): 2 L.append(a) 3 return L 4 5 print f(5) 6 print f(2) 输出 1 def f(a, L=None): 2 if L ...