poj2125最小点权覆盖
最小点权覆盖 转化为 最小割 然后网络流。
之前有道和这个差不多的题,伞兵。不过还是做不出来,又对着书拍的。现在好像懂了怎么建图了。 s-u-v-t若不被割开则存在 u-v 没被取到。
还是拆点,拆成出点和入点。注意图不要建反了,是出点集指向入点集 。
输出路径。这题因为最小割 不是在左边的边,就是在右边的边,所以 从源点对残余网络dfs 。 左边走不到的全是所求的出点的集合,右边能走到的全是入点的集合。
#include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include <queue> #include <stack> #include<math.h> using namespace std; int s;int e1; const int maxn=211; int n; const int INF=0xfffffff; int Min(int a,int b) {return a>b?b:a; } int level[maxn]; struct edge {int val;int to;int next;int op; }e[111111];int len;int head[maxn];void add(int from,int to,int val) {e[len].to=to;e[len].val=val;e[len].next=head[from];e[len].op=len+1;head[from]=len++;e[len].to=from; e[len].val=0;e[len].next=head[to];e[len].op=len-1;head[to]=len++; }bool bfs() {memset(level,0,sizeof(level));level[s]=1;int q[maxn*3]; int l=0;int r=0;q[r++]=s;while(l<r){int cur=q[l++];for(int i=head[cur];i!=-1;i=e[i].next){int cc=e[i].to;if(!e[i].val) continue;if(!level[cc]){level[cc]=level[cur]+1;q[r++]=cc;}}}return level[e1]; }int dfs(int x,int val) {if(x==e1) return val;int sum=0;for(int i=head[x];i!=-1&&val;i=e[i].next){int cc=e[i].to;if(!e[i].val) continue;if(level[cc]==level[x]+1){int t=dfs(cc,Min(val,e[i].val));e[i].val-=t;e[e[i].op].val+=t;sum+=t;val-=t;}}if(sum==0) level[x]=-1;return sum; }int dinic() {int ans=0;int t;while(bfs()){while(t=dfs(s,INF)) ans+=t;}return ans; } int ha[maxn*2]; void Hash(int x) {ha[x]=1;for(int i=head[x];i!=-1;i=e[i].next){int cc=e[i].to;if(!e[i].val) continue;if(!ha[cc]){Hash(cc);}} }void solve() {int ans=dinic();vector<int> q;printf("%d\n",ans);Hash(0);for(int i=1;i<=n;i++){if(!ha[i]) q.push_back(i);if(ha[i+n]) q.push_back(i+n);}int t=q.size();printf("%d\n",t);for(int i=0;i<t;i++)if(q[i]<=n) printf("%d -\n",q[i]);else printf("%d +\n",q[i]-n); } int main() {int m;while(scanf("%d%d",&n,&m)!=EOF){len=0;s=0;e1=2*n+1;memset(head,-1,sizeof(head));for(int i=1;i<=n;i++){int tt;scanf("%d",&tt);add(i+n,e1,tt);}for(int i=1;i<=n;i++){int tt;scanf("%d",&tt);add(s,i,tt);}for(int i=0;i<m;i++){int a;int b;scanf("%d%d",&a,&b);add(a,b+n,INF);}solve();}return 0;}
转载于:https://www.cnblogs.com/yigexigua/p/3890123.html
poj2125最小点权覆盖相关推荐
- [学习笔记]最小割之最小点权覆盖最大点权独立集
最小点权覆盖 给出一个二分图,每个点有一个非负点权 要求选出一些点构成一个覆盖,问点权最小是多少 建模: S到左部点,容量为点权 右部点到T,容量为点权 左部点到右部点的边,容量inf 求最小割即可. ...
- Hlg 1407 【最小点权覆盖】.cpp
题意: 给出一个图 该图的每个格子上有值 当扫射一行或一列的时候 格子上的值非0的就-1 输入: 给出n m 表示该图为n*m的图 接下来n*m的图写上格子的值 输出: 最少扫射几次可以使所有点权变成 ...
- POJ 3308 Paratroopers (对数转换+最小点权覆盖)
题意 敌人侵略r*c的地图.为了消灭敌人,可以在某一行或者某一列安置超级大炮.每一个大炮可以瞬间消灭这一行(或者列)的敌人.安装消灭第i行的大炮消费是ri.安装消灭第j行的大炮消费是ci现在有n个敌人 ...
- 网络流之最小点权覆盖和最大点权独立集学习
转载:http://yzmduncan.iteye.com/blog/1149057 二分图最小点覆盖和最大独立集都可以转化为最大匹配求解.在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为 ...
- 最小点权覆盖集最大点权独立集
最小点权覆盖集 最小点权覆盖集解决的是这样一个问题: 在二分图中,对于每条边,两个端点至少选一个,求所选取的点最小权值和. 方法: 1.先对图二分染色,对于每条边两端点的颜色不同 2.然后建立源点S, ...
- poj 3308(最小割求解最小点权覆盖)
火星人侵略地球,他们意图登陆破坏某个地区的兵器工厂.据探子回报,火星人登陆的地区为n*m大小的地域,而且每一个火星人的着陆点坐标已知. 火星人很强悍,只要有一个火星人着陆后能够幸存,他必定能毁坏这片区 ...
- P2172 [国家集训队]部落战争 二分图最小不相交路径覆盖
二分图最小不相交路径覆盖 #include<bits/stdc++.h> using namespace std; const int MAXN = 5550; const int MAX ...
- The Minimum Cycle Mean in a Digraph 《有向图中的最小平均权值回路》 Karp
文件链接 Karp在1977年的论文,讲述了一种\(O(nm)\)的算法,用来求有向强连通图中最小平均权值回路(具体问题请参照这里) 本人翻译(有删改): 首先任取一个节点 \(s\) ,定义 \(F ...
- 求一个指定点对的路径上的最大边权或最小边权(转)
dij贪心地取min(cur,pre)最大的路径 或者直接按权值排序,贪心地从最小或最大取,并茶几加点,联通停止即可... 我们还可以用二分..就是二分最大边权或者最小边权..重复上面类似kruska ...
最新文章
- 禁止 Python 子类覆盖父类方法
- python中使用函数编程的意义_总结Python编程中函数的使用要点
- 常用的图像增强处理办法
- 使用Python解压zip、rar文件
- Github上都没有的“网约车”项目,终于有人给写出来了!
- cloudflare 利用API将域名批量解析到cloudflare
- L1-018 大笨钟 (10 分)
- PHP Web Shell in browser
- mfc调取摄像头显示并截图_用OpenCV在MFC Dialog中Picture控件上显示摄像头采集实时视频...
- hdu 1232 经典并查集应用
- 傅里叶变换音频可视化_H5录音音频可视化-实时波形频谱绘制、频率直方图
- Yum介绍与常见用法
- 转:Vss2005局域网开发权限设置指南
- 博弈论——战略式博弈
- 调出远程桌面的任务管理器
- 将java项目打包为jar
- pg_bigm 处理中间模糊匹配 like ‘%xxoo%‘
- 斗破苍穹里的那些女人
- 英语关于计算机游戏作文,沉迷网络游戏的英语作文(精选5篇)
- A商品69元,买二送一;即买3个商品,付2件钱,小于3件时,按原价购买。