POJ2125

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

乍一看是要用点去覆盖边,联想到二分图的最小点权覆盖,通过拆点,我们可以得到二分图。每个点都拆成两个点,一个作为入点,另一个作为出点。于是我们构建了一个标准的二分图最小点权覆盖的模型

解决二分图最小点权覆盖的的算法并不复杂,创造一个源点和汇点,源点到左边的点连边,容量为对应点的权值,同理右边的点向汇点连边。然后运行最大流,就可以得到最小权值和。

下一步就是输出解决方案,也就是求最小割边集。在运行完最大流的残量网络中由源点出发BFS所有可以到达的点构成了源点集。对于剩下的边,如果满流且一个端点属于源点集而另一个端点不属于,则这条边属于最小割。

代码实现比较简单:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int maxn=110*2,maxm=5000,s=0,INF=9999999;
int n,m,t,cap[maxn][maxn],flow[maxn][maxn],w[maxn]; int augment(int fa[])
{
int d[maxn];
memset(d,0,sizeof(d));
d[s]=INF;
queue<int>q;q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=s;i<=t;i++)
{
if((d[i]!=0)||(cap[u][i]<=flow[u][i]))continue;
d[i]=min(d[u],cap[u][i]-flow[u][i]);
q.push(i);
fa[i]=u;
if(i==t)return d[t];
}
}
return d[t];
} int maxflow()
{
int fa[maxn];
int ans=0; while(true)
{
int nflow=augment(fa);
if(nflow==0)return ans;
ans+=nflow;
for(int i=t;i!=s;i=fa[i])
{
flow[fa[i]][i]+=nflow;
flow[i][fa[i]]-=nflow;
}
}
}
vector<int> mincut()
{
bool vis[maxn];
memset(vis,0,sizeof(vis));
vis[s]=true;
queue<int>q;
q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=s;i<=t;i++)
{
if((vis[i])||(cap[u][i]<=flow[u][i]))continue;
vis[i]=true;
q.push(i);
}
}
vector<int>ans;
for(int i=s;i<=t;i++)
if(vis[i])for(int j=s;j<=t;j++)
if(!vis[j]&&cap[i][j]==flow[i][j]&&cap[i][j]>0)
{
if(i==s){ans.push_back(j);}
if(j==t){ans.push_back(i);}
}
return ans;
} void print(vector<int> vec)
{
cout<<vec.size()<<endl;
for(int i=0;i<vec.size();i++)
{
if(vec[i]<=n)cout<<vec[i]<<" -"<<endl;
else cout<<vec[i]-n<<" +"<<endl;
}
}
int main()
{
ios::sync_with_stdio(false);
memset(cap,0,sizeof(cap));memset(flow,0,sizeof(flow));
cin>>n>>m;
t=n*2+1;
for(int i=1;i<=n*2;i++)
cin>>w[i];
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;
cap[a][b+n]=INF;
}
for(int i=1;i<=n;i++)
{
cap[s][i]=w[i+n];
cap[i+n][t]=w[i];
}
cout<<maxflow()<<endl;
print( mincut() );
return 0;
}

  东北欧赛区的题目还是很给力的

POJ 2125 Destroying The Graph 二分图 最小点权覆盖的更多相关文章

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

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

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

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

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

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

  4. POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割

    思路来源:http://blog.csdn.net/lenleaves/article/details/7873441 求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边, 只要用最终的剩余网络 ...

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

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

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

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

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

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

  8. POJ3308 Paratroopers(最小割/二分图最小点权覆盖)

    把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖. 此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运 ...

  9. POJ 3308 Paratroopers(最大流最小割の最小点权覆盖)

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

随机推荐

  1. 机器人局部避障的动态窗口法(dynamic window approach) (转)

    源:机器人局部避障的动态窗口法(dynamic window approach) 首先在V_m∩V_d的范围内采样速度: allowable_v = generateWindow(robotV, ro ...

  2. 【uoj57】 WC2013—平面图

    http://uoj.ac/problem/57 (题目链接) 题意 给出二位平面上n个点,点之间有一些连线,连线不在顶点之外的地方相交,将平面分为若干个区域.给出一些询问点对,问从这个点所在的区域走 ...

  3. Java XML解析器

    使用Apache Xerces解析XML文档 一.技术概述 在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组 ...

  4. Jenkins SSH timeout

    问题如下: Started by user carzone Building -test SSH: Connecting from host [jenkins232] SSH: Connecting ...

  5. Vue 响应式总结

    有些时候,不得不想添加.修改数组和对象的值,但是直接添加.修改后getter.setter又失去了. 由于 JavaScript 的限制, Vue 不能检测以下变动的数组: 当你利用索引直接设置一个项 ...

  6. centos服务器设置代理上网的方法

    这里以centos7.0为例,记录代理服务器设置过程: 1.全局的代理设置: vi /etc/profile 添加下面内容 http_proxy = http://username:password@ ...

  7. thinkphp CURD 1

    二.ThinkPHP 3 读取数据    (重点)    对数据的读取 Read    $m=new Model('User');    $m=M('User'); select    $m-> ...

  8. 日历视图(CalendarView)组件的功能和用法

    日历视图(CalendarView)可用于显示和选择日期,用户既可选择一个日期,也可通过触摸来滚动日历.如果希望监控该组件的日历改变,可调用CalendarView的setOnDateChangeLi ...

  9. php判断IE浏览器

    <?php/** * 检测用户当前浏览器 * @return boolean 是否ie浏览器 */ function chk_ie_browser() { $userbrowser = $_SE ...

  10. 细数JDK里的设计模式

    原文出处: javacodegeeks   译文出处:deepinmind 这也是篇老文了,相信很多人也看过.前面那些废话就不翻译了,直接切入正题吧~ 结构型模式: 适配器模式: 用来把一个接口转化成 ...