思路来源: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. bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp

    题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2369  Solved: 1266[Submi ...

  2. selenium 学习笔记 ---新手学习记录(3) 问题总结(java)

    1.验证码简单处理 /** * 验证码等待输入函数 * */ private void ZcYzm(WebDriver driver){ boolean flag=false; while(flag= ...

  3. GC算法之串行并行并发

    串行收集器: 用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高.但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器.当然,此收集器也可以用在小数据量(100M左右)情况下的多 ...

  4. setTimeout 虚假的“异步”

    看这篇http://www.laruence.com/2009/09/23/1089.html 所以实际上 setTimeout更像是任务按照队列执行  经过setTimeout设置后任务放在了队尾 ...

  5. 《刺杀金正恩》1080p全高清无水印,附中文字幕 bt种子下载,附字母(百度网盘/360云盘)

    <刺杀金正恩>1080p全高清无水印,附中文字幕下载(百度网盘/360云盘) 种子和字幕下载地址: thunder://QUFlZDJrOi8vfGZpbGV8JUU5JTg3JTg3JU ...

  6. MultiView空间例子

    CSS代码: body { font-size:11pt; font-family:宋体; } .mainTitle { font-size:11pt; font-weight:bold; font- ...

  7. mfc删除标题和边框

    //删除标题和边框WS_CAPTION和WS_BORDER风格 ModifyStyle(WS_CAPTION, 0);ModifyStyle(WS_BORDER, 0);

  8. C++模板:二分图匹配

    int Dfs(int k){ for(int i=0;i<v[k].size();i++){ int a=v[k][i]; if(used[a]==0){ used[a]=1; if(link ...

  9. Spring 面试复习

    1   singleton 和 prototype singleton作用域:当把一个Bean定义设置为singleton作用域是,Spring IoC容器中只会存在一个共享的Bean实例,并且所有对 ...

  10. PhoneGap 3.0 安装

    PhoneGap 3.0  已经出来有一段时间了.3.0 提供了使用Node.js 安装,使用命令行创建.编译.运行项目.也就是可以抛弃eclipse,完全使用命令.记事本开发phonegap 项目了 ...