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-}\).求删去该图的最小花费,并输出解 分析:简而言之就是用最小权值的点集去覆盖所有的边 ...
随机推荐
- centos7 连接打印机
centos7 连接打印机 2017-08-07 15:05:33 五岳寻仙客 阅读数 2531更多 分类专栏: Liunx的日常使用 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版 ...
- bond4以及vlan子接口配置
场景: 前提,交换机的配置由网络工程师配合! 1.跨交换机做bond,模式为LACP,linux双网卡做bond4,模式为4: 2.系统为centos7.0-123: 3.服务器仅有两张万兆网卡,为e ...
- shell初学之nginx(负载均衡)
创建三个以域名区分的网站a.com,b.com,c.com:访问a.b时,分别显示a.b两个网站的内容:访问c时,会出现依次显示两次a网站的内容,一次b网站的内容. 1 #!/bin/bash 2 s ...
- linux中级之lvs配置(命令)
一.nat模式配置 环境说明: DS:nat网卡(自动获取也可以,充当vip): 192.168.254.13 255.255.255.0 vmnet3网卡(仅主机): 172.16.100.1 25 ...
- -bash: $'\201ccd': δ 的错误是linux编码问题(Centos7)
如果目录是中文目录,你的编码为: [root@dbbd-api01 ~]# cat /etc/locale.conf LANG=zh_CN.GB18030 [root@dbbd-api01 ~]# 那 ...
- 树莓派 PICO基础教程(基于MicroPython)
目录 1 树莓派 PICO 简介 1.1 简介 1.2 配置 [^2] 1.3 引脚图 1.4 尺寸 2 安装 2.1 烧录固件 2.2 安装IDE(Thonny IDE) 2.3 离线运行程序 3 ...
- 微信小程序在ios系统不兼容new Date('yyyy-mm-dd')
微信小程序中使用new Date('2021-04-01 10:11:20')来转换时间在苹果手机不生效 兼容写法为new Date('2021/04/01 10:11:20')
- 八、.net core(.NET 6)配置读取appsettings文件内容的通用功能
添加通用读取配置文件功能 在Wsk.Core.Package项目下,新增Microsoft.Extensions.Configuration包: 在启动项目下,设置appsettings.json属 ...
- 学妹问,学网站开发还是打 ACM?
聊聊我的选择 大家好,我是鱼皮,前几天看到一位大一计科同学的问题:我想学做 Web 项目,又想学算法搞 ACM,如何取舍呢 ? ACM 是国际大学生程序设计竞赛,旨在展示大学生创新能力.团队精神.编写 ...
- 从C到C++过渡的3个原因
从C到C++过渡的3个原因 3 reasons to transition from C to C++ 几十年来,嵌入式软件工程师们一直在争论他们是否应该使用C或C++.根据2019年嵌入式市场调查, ...