思路来源:http://blog.csdn.net/lenleaves/article/details/7873441

求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边,
只要用最终的剩余网络进行一次遍历就可以了,比较简单。
建图:同样是一个二分图,左边的点代表去掉出边,
右边的点代表去掉入边(小心别弄混),左边去掉出边的点与源点相连,
容量为wi- 。
然后更据给出的弧进行连线,权值为INF
 

使用很好理解的EK算法:(360MS)
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <climits>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mm(a) memset((a),0,sizeof((a)))
#define ll long long
using namespace std; const int INF = 0x3f3f3f3f;
const int MAXN = ; queue <int> que; int vis[MAXN], res[MAXN], pre[MAXN];
int n, m, map[MAXN][MAXN];
int src, des;
stack <int> ss; bool bfs(int src, int des){
int index;
memset(pre, -, sizeof(pre));
while(!que.empty()) que.pop();
pre[src] = ;
que.push(src);
while(!que.empty()){
index = que.front();
que.pop();
for(int i = src; i <= des; ++i){
if(pre[i] == - && map[index][i] > ){
pre[i] = index;
if(i == des) return true;
que.push(i);
}
}
}
return false;
} int MaxFlow(int src, int des){
int i, maxflow = ;
while(bfs(src, des)){
int minflow = INF;
for(i = des; i != src; i = pre[i])
minflow = min(minflow, map[pre[i]][i]);
for(i = des; i != src; i = pre[i]){
map[pre[i]][i] -= minflow;
map[i][pre[i]] += minflow;
}
maxflow += minflow;
}
return maxflow;
} void init(){
mm(map);mm(vis);
} void dfs(int p){
if(vis[p]) return ;
vis[p] = true;
for(int i = src; i < des; ++i)
if(!vis[i] && map[p][i]) dfs(i);
} void solve(){
int i, x, y, ans = , temp;
init();
for(i = ; i <= n; ++i)
scanf("%d",&map[n + i][n * + ]);
for(i = ; i <= n; ++i)
scanf("%d",&map[][i]);
for(i = ; i <= m; ++i){
scanf("%d%d",&x,&y);
map[x][y + n] = INF;
} n = n << ;
src = , des = n + ;
ans = MaxFlow(src, des); dfs(); printf("%d\n",ans);
n = n >> ; for(i = ; i <= n; ++i){
if(!vis[i])
ss.push(i);
if(vis[i + n])
ss.push(i + n);
}
printf("%d\n",ss.size());
while(!ss.empty()){
temp = ss.top();
ss.pop();
if(temp <= n) printf("%d -\n",temp);
else printf("%d +\n",temp - n);
}
} int main(){
while(EOF != scanf("%d%d",&n,&m)) solve();
return ;
}

使用SAP + GAP 优化:(79MS) 
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <climits>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mm(a) memset((a),0,sizeof((a)))
#define ll long long
using namespace std; const int INF = 0x3f3f3f3f;
const int MAXN = ; int n, m, map[MAXN][MAXN], dis[MAXN], gap[MAXN];
int src, des;
bool vis[MAXN];
stack <int> ss; void init(){
mm(dis);mm(gap);mm(map);mm(vis);
} int sap(int u,int flow){
if(u == des) return flow;
int ans = , i, t;
for(i = ; i <= n + ; ++i)
if(map[u][i] && dis[u] == dis[i] + ){
t = sap(i, min(flow - ans, map[u][i]));
map[u][i] -= t, map[i][u] += t,ans += t;
if(ans == flow) return ans;
}
if(dis[src] >= n + ) return ans;
if(!--gap[dis[u]]) dis[src] = n + ;
++gap[++dis[u]];
return ans;
} void dfs(int p){
if(vis[p]) return ;
vis[p] = true;
for(int i = ; i < n + ; ++i)
if(!vis[i] && map[p][i]) dfs(i);
} void solve(){
int i, x, y, ans = , temp;
init();
for(i = ; i <= n; ++i)
scanf("%d",&map[n + i][n * + ]);
for(i = ; i <= n; ++i)
scanf("%d",&map[][i]);
for(i = ; i <= m; ++i){
scanf("%d%d",&x,&y);
map[x][y + n] = INF;
} n = n << ;
src = , des = n + ;
for(gap[] = n + ; dis[src] < n + ; )
ans += sap(src,INF); dfs(); printf("%d\n",ans);
n = n >> ; for(i = ; i <= n; ++i){
if(!vis[i])
ss.push(i);
if(vis[i + n])
ss.push(i + n);
}
printf("%d\n",ss.size());
while(!ss.empty()){
temp = ss.top();
ss.pop();
if(temp <= n) printf("%d -\n",temp);
else printf("%d +\n",temp - n);
}
} int main(){
while(scanf("%d%d",&n,&m)!=EOF) solve();
return ;
}

POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. poj 3308 Paratroopers(二分图最小点权覆盖)

    Paratroopers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8954   Accepted: 2702 Desc ...

随机推荐

  1. python安装集成包

    anaconda, 包含各种科学运算包以及astropy.装完它一劳永逸. https://www.continuum.io/downloads

  2. ASP.NET MVC5 学习笔记-5 测试

    1. 测试步骤 准备 执行 检查 2. 创建单元测试 注意:单元测试不要包含数据库操作,包含数据库操作的一般成为集成测试. 2.1 编写测试代码 namespace AspNetMVCEssentia ...

  3. access数据库 top语句失效解决方法

    使用查询语句  select   top 1  *  from  News  order  by  [PublicTime] desc   就不一定管用了,如果News表里面的PublicTime字段 ...

  4. 在Spring Boot启动后执行指定代码

    在开发时有时候需要在整个应用开始运行时执行一些特定代码,比如初始化环境,准备测试数据等等. 在Spring中可以通过ApplicationListener来实现相关的功能,不过在配合Spring Bo ...

  5. HDU 1997 汉诺塔VII

    题解参考博客: http://blog.csdn.net/hjd_love_zzt/article/details/9897281 #include <cstdio> ],yes; int ...

  6. Mysql 创建联合主键

    Mysql 创建联合主键2008年01月11日 星期五 下午 5:21使用primary key (fieldlist)      比如:   create table mytable (       ...

  7. 图像检索:一维直方图+EMD距离

    EMD距离具体介绍已经在在这里已经给出. 思路:我们把一张图像的归一化的一维直方图作为signature的权值,也就是一般在比較两幅图像颜色直方图的EMD距离时,每一行的坐标一样,仅仅是权重值不一样. ...

  8. GCC编译四阶段

    Linux下程序编译的四个阶段:预处理.编译.汇编.链接 GCC: GUN  C Compiler 但现在不只局限于c语言 预处理(Preprocessing): gcc  -E  hello.c - ...

  9. Java多线程之synchronized(五)

    上篇介绍了用synchronized修饰static方式来实现“Class 锁”,今天要介绍另一种实现方式,synchronized(class)代码块,写法不一样但是作用是一样的.下面我附上一段代码 ...

  10. C#面向对象编程基础-喜课堂笔记

    **************[5][C#面向对象编程基础]第1讲:类与对象****************                 *************2.1.1_类与对象的概念**** ...