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 最小点权集--最小割--最大流的更多相关文章
- POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割
思路来源:http://blog.csdn.net/lenleaves/article/details/7873441 求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边, 只要用最终的剩余网络 ...
- POJ 3308 Paratroopers(最小点权覆盖)(对数乘转加)
http://poj.org/problem?id=3308 r*c的地图 每一个大炮可以消灭一行一列的敌人 安装消灭第i行的大炮花费是ri 安装消灭第j行的大炮花费是ci 已知敌人坐标,同时消灭所有 ...
- POJ2125 Destroying The Graph (最小点权覆盖集)(网络流最小割)
Destroying The Graph Time Limit: 2000MS Memo ...
- POJ2125 Destroying The Graph(二分图最小点权覆盖集)
最小点权覆盖就是,对于有点权的有向图,选出权值和最少的点的集合覆盖所有的边. 解二分图最小点权覆盖集可以用最小割: vs-X-Y-vt这样连边,vs和X部点的连边容量为X部点的权值,Y部和vt连边容量 ...
- POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)
题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...
- poj 2125 Destroying The Graph (最小点权覆盖)
Destroying The Graph http://poj.org/problem?id=2125 Time Limit: 2000MS Memory Limit: 65536K ...
- POJ 2125 Destroying the Graph 二分图最小点权覆盖
Destroying The Graph Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8198 Accepted: 2 ...
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
POJ2125 题意简述:给定一个有向图,要通过某些操作删除所有的边,每一次操作可以选择任意一个节点删除由其出发的所有边或者通向它的所有边,两个方向有不同的权值.问最小权值和的解决方案,要输出操作. ...
- POJ - 2125 Destroying The Graph (最小点权覆盖)
题意:给一张图,现在要删去所有的边,删去一个点的所有入边和所有出边都有其对应\(W_{i+}\)和\(W_{i-}\).求删去该图的最小花费,并输出解 分析:简而言之就是用最小权值的点集去覆盖所有的边 ...
随机推荐
- Xshell 远程使用vim打开文件不能使用右键复制粘贴(右键显示可视)的问题
Xshell 远程使用vim打开文件不能使用右键复制粘贴(右键显示可视)的问题 Debian9.4系统不能再VIM打开文件界面不能使用右键复制粘贴 root@debian:~# vim /usr/sh ...
- stress工具使用指南和结果分析(好好好测试通过)
stress工具使用指南和结果分析 佛心看世界关注 0.1152019.05.13 09:17:35字数 547阅读 1,112 #stress `stress' imposes certain ty ...
- Docker镜像的仓库及底层依赖的核心技术(3)
一.docker镜像的仓库 仓库分为公共仓库和私有仓库 DockerHub的官方仓库:https://hub.docker.com DockerPool社区仓库:https://dl.dockerpo ...
- 回车与换行的区别:CRLF、CR、LF
引言 以下是 MySQL 8 导出数据的窗口,导出数据时需要选择记录分隔符,这就需要你明白 CRLF.CR 和 LF 分别代表什么,有何区别,否则可能导出数据会出现莫名其米的问题. 名词解释 CR:C ...
- IDEA 安装 zookeeper 可视化管理插件
1. 安装 zookeeper 插件 打开 IDEA->Settings->Plugins,然后在 Marketplace 输入 "zookeeper" 如下: 插件安 ...
- DOCKER学习_013:Dockerfile配置指令ENTRYPOINT详解
前面已经介绍了一些Dockerfile的一些指令,对于ENTRYPOINT和CMD也有介绍实验 一 ENTRYPOINT和CMD配置使用 ENTRYPOINT相当于CMD,是配置容器后的一个指令,但是 ...
- python基础之迭代器、生成器、装饰器
一.列表生成式 a = [0,1,2,3,4,5,6,7,8,9] b = [] for i in a: b.append(i+1) print(b) a = b print(a) --------- ...
- MyBatis 缓存机制(十三)
什么是缓存 缓存就是内存中的一个对象,用于对数据库查询结果的保存,用于减少与数据库的交互次数从而降低数据库的压力,进而提高响应速度. MyBatis 缓存机制原理 Mybatis 缓存机制原理是将第一 ...
- SpringBoot + WebSocket 实现答题对战匹配机制
概要设计 类似竞技问答游戏:用户随机匹配一名对手,双方同时开始答题,直到双方都完成答题,对局结束.基本的逻辑就是这样,如果有其他需求,可以在其基础上进行扩展 明确了这一点,下面介绍开发思路.为每个用户 ...
- Linux(CentOS 7) 安全加固之非业务端口服务关闭 postfix port 25
目录 关闭TCP 25 端口对应的服务 1. 确认对应端口的进程 2. 查找与关闭对应服务 3. 确认结果,端口已关闭 关闭TCP 25 端口对应的服务 [0 root@Qvps /root] #ca ...