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-}\).求删去该图的最小花费,并输出解 分析:简而言之就是用最小权值的点集去覆盖所有的边 ...
随机推荐
- Spec2006使用说明
Spec2006使用说明 五 10 十月 2014 By penglee 工具介绍 SPEC CPU 2006 benchmark是SPEC新一代的行业标准化的CPU测试基准套件.重点测试系统的处理器 ...
- Windows(受控主机)上配置
Powershell版本要求及配置 windows需要使用Powershell4.0及以上版本,入下图所示,如果不是4.0及以上的需要升级 一.升级Powershell至3.0+ 1. 下载并安装Mi ...
- 用urllib库几行代码实现最简单爬虫
""" 使用urllib.request()请求一个网页内容,并且把内容打印出来. """ from urllib import reque ...
- CentOS7安装vncserver(启动失败及连接黑屏解决办法)
CentOS7安装vncserver(启动失败及连接黑屏解决办法) 转载weixin_34167043 最后发布于2017-11-09 15:11:00 阅读数 42 收藏 展开 AutoSAR入门 ...
- session.flush()与session.clear()区别与使用环境
session是有一级缓存的,目的是为了减少查询数据库的时间,提高效率,生命周期与session是一样的 session.flush() 是将session的缓存中的数据与数据库同步 事物提交失败 缓 ...
- JVM-运行时数据区之PC寄存器
1.运行时数据区图 运行时数据区是在类加载完成后所经历的阶段,当我们通过前面的:类的加载 --> 验证 --> 准备 --> 解析 --> 初始化,这几个阶段完成后,执行引擎就 ...
- 解决mysql无法远程连接的问题
前言 最近开发中遇到一个问题,mysql在服务器本地可以登录,但是远程通过3306端口却不可以.这个问题困扰了我一周之久,终于在今天解决了.在解决的过程中试了很多的方法,遂记录下来,希望能给大家一些提 ...
- Spring的三种注入
在学习Spring的过程中,其中一个很重要的就是依赖注入DI,在此总结一下 注入方式有三种: 一.构造器注入 二.Set方式注入(重点) 三.扩展方式注入 构造器注入: a.默认使用无参构造函数创建对 ...
- C# MVC(File)控件多张图片上传加预览
刚来公司实习,老板叫我写一个积分商城网站.用的是公司的框架结构搭建的后台,所以后台的图片上传不需要自己写.但是前台的评价图片就需要自己手写了,在网上找了很多代码发现都用不了.问了很多人也都没有实现! ...
- Java基础知识之this关键字知识讲解
this关键字这里对java中this关键字的基础知识进行讲解,希望对热爱java的小伙伴有帮助!! /* this关键字代表了所属函数的调用者对象. this关键字的作用: 1. 如果存在同名成员变 ...