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 ...
随机推荐
- poj 3243 Clever Y 高次方程
1 Accepted 8508K 579MS C++ 2237B/** hash的强大,,还是高次方程,不过要求n不一定是素数 **/ #include <iostream> #inclu ...
- 转:说说angularjs中的$parse和$eval
说说AngularJS中的$parse和$eval AngularJS的初学者常常会对$parse和$eval两个内建服务感到有些困惑,今天我们就来说说AngularJS中的$parse和$eval. ...
- html文件中文在浏览器中显示乱码问题解决
利用浏览器打开html文件时,中文显示乱码,如下是原文件的内容 1 <html> 2 <head> 3 <title> ...
- perl5 第四章 列表和数组变量
第四章 列表和数组变量 by flamephoenix 一.列表二.数组--列表的存贮 1.数组的存取 2.字符串中的方括号和变量替换 3.列表范围 4.数组的输出 5.列表/数组的长度 ...
- SQL实现递归及存储过程中 In() 参数传递解决方案
1.SQL递归 在SQL Server中,我们可以利用表表达式来实现递归算法,一般用于阻止机构的加载及相关性处理. -->实现: 假设OrganiseUnit(组织机构表)中主要的三个字段为Or ...
- Cow Acrobats(贪心)
Cow Acrobats Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3686 Accepted: 1428 Desc ...
- php单元測试
你是否在程序开发的过程中遇到下面的情况:当你花了非常长的时间开发一个应用后,你觉得应该是大功告成了,可惜在调试的时候,老是不断的发现bug,并且最可怕的是,这些bug是反复出现的,你可能发现这些bug ...
- Python 参数传递
python中的变量: 一个变量是局部还是全局,在编译函数的时候就已经决定,因此读变量值的时候也不会逐层向外查找.变量是全局还是局域,根据如下3条: 1. 如果函数内部有global语句,那么它声明的 ...
- BZOJ 2100: [Usaco2010 Dec]Apple Delivery( 最短路 )
跑两遍最短路就好了.. 话说这翻译2333 ---------------------------------------------------------------------- #includ ...
- webviewactivity
WebView注意点,注释里有说明 package com.example.suneyaenews; import com.example.http.HttpThread; import androi ...