POJ1815 Friendship(字典序最小最小割割边集)
看了题解。当时也觉得用邻接矩阵挺好写的,直接memset;然而邻接矩阵不懂得改,于是就放开那个模板,写了Dinic。。
方法是,按字典序枚举每一条满流的边,然后令其容量减1,如果最大流改变了,这条边就是属于某个最小割;接下来一直重复下去,直到得到一个割边集,而它自然是字典序最小的。
我在每次某条边容量减1后都重新计算一遍最大流,简单。。其实我知道是有这么一回事,把边容量减1后可以利用当前求出的最大流来得出新的最大流,这样会快一些,不过我不会。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF (1<<30)
int n,vs,vt,NV,c[][],f[][],level[];
bool bfs(){
memset(level,,sizeof(level));
bool vis[]={};
vis[vs]=;
int que[],front=,rear=;
que[rear++]=vs;
while(front<rear){
int u=que[front++];
for(int v=; v<=NV; ++v){
if(vis[v] || c[u][v]==f[u][v]) continue;
level[v]=level[u]+;
vis[v]=;
que[rear++]=v;
} }
return vis[vt+n];
}
int dfs(int u,int s){
if(u==vt+n) return s;
int res=s,tmp;
for(int v=; v<=NV; ++v){
if(level[v]!=level[u]+ || c[u][v]==f[u][v]) continue;
tmp=dfs(v,min(s,c[u][v]-f[u][v]));
f[u][v]+=tmp;
f[v][u]-=tmp;
s-=tmp;
}
return res-s;
}
int dinic(){
int res=;
while(bfs()) res+=dfs(vs,INF);
return res;
}
int main(){
int a;
scanf("%d%d%d",&n,&vs,&vt);
NV=n<<;
for(int i=;i<=n;++i){
c[i][i+n]=;
for(int j=;j<=n;++j){
scanf("%d",&a);
if(i==j || a==) continue;
c[i+n][j]=INF;
}
}
c[vs][vs+n]=INF; c[vt][vt+n]=INF;
if(c[vs+n][vt]){
puts("NO ANSWER!");
return ;
}
int ans=dinic();
printf("%d\n",ans);
for(int i=; i<=n&&ans; ++i){
if(i==vs||i==vt || f[i][i+n]==) continue;
memset(f,,sizeof(f));
c[i][i+n]=;
if(dinic()<ans){
--ans;
printf("%d ",i);
}else{
c[i][i+n]=;
}
}
return ;
}
POJ1815 Friendship(字典序最小最小割割边集)的更多相关文章
- POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)
题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...
- hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...
- POJ2125 Destroying The Graph (最小点权覆盖集)(网络流最小割)
Destroying The Graph Time Limit: 2000MS Memo ...
- POJ2125 Destroying The Graph(二分图最小点权覆盖集)
最小点权覆盖就是,对于有点权的有向图,选出权值和最少的点的集合覆盖所有的边. 解二分图最小点权覆盖集可以用最小割: vs-X-Y-vt这样连边,vs和X部点的连边容量为X部点的权值,Y部和vt连边容量 ...
- POJ 2125 最小点权覆盖集(输出方案)
题意:给一个图(有自回路,重边),要去掉所有边,规则:对某个点,可以有2种操作:去掉进入该点 的所有边,也可以去掉出该点所有边,(第一种代价为w+,第二种代价为w-).求最小代价去除所有边. 己思:点 ...
- [leetcode](4.21)2. 按字典序排列最小的等效字符串
给出长度相同的两个字符串:A 和 B,其中 A[i] 和 B[i] 是一组等价字符.举个例子,如果 A = "abc" 且 B = "cde",那么就有 'a' ...
- HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]
嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1569 Time Limi ...
- 最小点权覆盖集&最大点权独立集
最小点权覆盖集 二分图最小点权覆盖集解决的是这样一个问题: 在二分图中,对于每条边,两个端点至少选一个,求所选取的点最小权值和. 方法: 1.先对图二分染色,对于每条边两端点的颜色不同 2.然后建立源 ...
- [Swift-2019力扣杯春季决赛]2. 按字典序排列最小的等效字符串
给出长度相同的两个字符串:A 和 B,其中 A[i] 和 B[i] 是一组等价字符.举个例子,如果 A = "abc" 且 B = "cde",那么就有 'a' ...
随机推荐
- 3ds max不显示网格,转换为可编辑面片
按G就消失了,快捷键 F3/F4切换线框和面片模式的显示
- Android 天气曲线
参考:http://blog.csdn.net/qy274770068/article/details/51560148
- 求n阶方阵的值(递归)
若有n*n阶行列式A,则: |A|=A[1][1]*M[1][1]+A[1][2]*M[1][2]+...A[1][n]*M[1][n]:其中M[1][i] 表示原矩阵元素A[1][i]的代数余子式: ...
- Java中读取xml方法
package zaxiang; import java.io.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parser ...
- iptables下state的4种形式
ESTABLISHED,NEW,RELATED,INVALID. 注意:TCP/IP 标准描述下,UDP及ICPM数据包是没有连接状态的,但在state模块的描述下,任何数据包都有连接状态. ESTA ...
- MVC缓存02,使用数据层缓存,添加或修改时让缓存失效
在"MVC缓存01,使用控制器缓存或数据层缓存"中,在数据层中可以设置缓存的有效时间.但这个还不够"智能",常常希望在编辑或创建的时候使缓存失效,加载新的数据. ...
- Notice: Only variable references should be returned by reference(PHP版本兼容性问题)
摘自:http://sushener.spaces.live.com/blog/cns!BB54050A5CFAFCDD!435.entry PHP5一个很让人恼火的一点就是BC(向后兼容)不是很理想 ...
- 攻城狮在路上(叁)Linux(二十七)--- 压缩与打包之常见的压缩命令
前面讲到,linux中的后缀名没有特殊的意义,一般是作为不同文件类型的标识而已.下面是与打包.压缩相关的后缀名介绍: *.z:compress程序压缩文件 *.gz:gzip程序压缩文件 *.bz2: ...
- 6-03使用SQL语句一次型向表中插入多行数据
通过将现有表中的数据添加到已存在的表中: INSERT INTO <表名><列名> SELECT<列名> FROM<源表名> 将UserInfo的数据添 ...
- hdu 4753 2013南京赛区网络赛 记忆化搜索 ****
看到范围基本可以想到dp了,处理起来有点麻烦 #include<iostream> #include<cstdio> #include<cstring> #incl ...