POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割
思路来源:http://blog.csdn.net/lenleaves/article/details/7873441
//#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 二分图 + 最小点权覆盖 + 最小割的更多相关文章
- POJ 3308 Paratroopers(最小点权覆盖)(对数乘转加)
http://poj.org/problem?id=3308 r*c的地图 每一个大炮可以消灭一行一列的敌人 安装消灭第i行的大炮花费是ri 安装消灭第j行的大炮花费是ci 已知敌人坐标,同时消灭所有 ...
- POJ2125 Destroying The Graph(二分图最小点权覆盖集)
最小点权覆盖就是,对于有点权的有向图,选出权值和最少的点的集合覆盖所有的边. 解二分图最小点权覆盖集可以用最小割: vs-X-Y-vt这样连边,vs和X部点的连边容量为X部点的权值,Y部和vt连边容量 ...
- POJ 2125 Destroying the Graph 二分图最小点权覆盖
Destroying The Graph Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8198 Accepted: 2 ...
- POJ2125 Destroying The Graph (最小点权覆盖集)(网络流最小割)
Destroying The Graph Time Limit: 2000MS Memo ...
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
POJ2125 题意简述:给定一个有向图,要通过某些操作删除所有的边,每一次操作可以选择任意一个节点删除由其出发的所有边或者通向它的所有边,两个方向有不同的权值.问最小权值和的解决方案,要输出操作. ...
- 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 (最小点权覆盖)
题意:给一张图,现在要删去所有的边,删去一个点的所有入边和所有出边都有其对应\(W_{i+}\)和\(W_{i-}\).求删去该图的最小花费,并输出解 分析:简而言之就是用最小权值的点集去覆盖所有的边 ...
- poj 3308 Paratroopers(二分图最小点权覆盖)
Paratroopers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8954 Accepted: 2702 Desc ...
随机推荐
- 09-C语言数组
目录: 一.使用xcode编辑工具 二.数组 三.数组遍历 四.多维数组 回到顶部 一.使用xcode编辑工具 1 打开xcode程序 2 创建一个项目 OSX -> Application - ...
- Stack trace对性能的影响
package ceshi; public class ExceptionTest { public long maxLevel = 20; public static void main(Strin ...
- Protel99se教程三:新建PCB文件以及PCB基本设定
在上一课,我们绘制好SCH原理图后,在这一节课开始,我们介绍,如何将SCH转化成PCB文件,在这一节课,我们主要给大家讲解,如果新建PCB文件以及载入封装图. 第一步:在Documents目录下,新建 ...
- Android之ListView性能优化
ListView滚动速度优化主要可以应用以下几点方法来实现: 1.使用Adapter提供的convertView convertView是Adapter提供的视图缓存机制,当第一次显示数据的时候,ad ...
- android 自定义百度地图放大缩小
自定义实现Android百度地图的缩放图标,需要自定义一个缩放控件,实现效果如下: 这里的缩放效果,实现了点击按钮可以对地图的放大缩小,通过手势放大与缩小也控制缩放图标的可用状态.具体实现如下: zo ...
- Mark Russinovich 的博客:Windows Azure 主机更新:原因、时间和方式
Mark Russinovich的技术博客涵盖 Windows故障排除.技术和安全等主题. Windows Azure主机更新:原因.时间和方式 Windows Azure的计算平台(其中包括 ...
- Android Manifest.xml 结构详解
关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activities ...
- android api 中文 (74)—— AdapterView.AdapterContextMenuInfo
前言 本章内容是android.widget.AdapterView.AdapterContextMenuInfo,版本为Android 2.3 r1,翻译来自"cnmahj",欢 ...
- WLAN和WIFI的区别
在刚刚为大家介绍的wifi上网是什么意思?文章中为大家介绍了什么wifi无线上网,但大家可能会有这样的疑问,听说最多的应该是WLAN无线上网,很多笔记本电脑使用的都是WLAN无线上网,那么wlan和w ...
- CSS中 清除浮动解决“包含问题”
今天看到大神对浮动定位作了个详细的分析 刚好就分析了当时任务三遇到的问题 在一个div中定义了三个div,让横向排列,结果父元素div的背景色显示不出来了 ,这是个经典问题----包含浮动 < ...