POJ 2125 Destroying The Graph 二分图 最小点权覆盖
来源:互联网 发布:方便面怎么煮好吃知乎 编辑:程序博客网 时间:2024/06/06 03:24
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;}
东北欧赛区的题目还是很给力的
0 0
- POJ 2125 Destroying The Graph 二分图最小点权覆盖 最小割
- 【二分图|最小点权覆盖】POJ-2125 Destroying The Graph
- POJ 2125 Destroying The Graph(二分图最小点权覆盖)
- POJ 2125 Destroying The Graph 二分图最小点权覆盖集
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- POJ 2125 Destroying The Graph 最小点权覆盖
- POJ 2125 Destroying The Graph 最小点权覆盖集
- 【POJ】2125 Destroying The Graph 最小点权覆盖
- poj 2125 Destroying The Graph 最小点权覆盖
- Destroying The Graph (poj 2125 最小点权覆盖)
- poj 2125 Destroying The Graph 最小点权覆盖集
- poj 2125 Destroying The Graph(最小点权覆盖集)
- 选夫婿1(结构体)
- K上升序列总和
- 广义线性模型
- 自己动手搭梯子——从vps到SSR菜鸟教程
- 278. First Bad Version
- POJ 2125 Destroying The Graph 二分图 最小点权覆盖
- Python else语句
- 入门训练 Fibonacci数列
- 【详解】嵌入式开发中固件的烧录方式
- java输入输出(二)
- 内核链
- Web基础之CSS3
- 268. Missing Number
- Hexo 博客空间