ZOJ 2532 网络流最小割
求最小割的问题。
题意:已知网络中有n个源点,m的中转站(也就是节点),一个汇点(编号为0)。给出网络,求一些边(增大这个边就可以增大汇点流量的边)。
思路:一开始代码只找了有流=0就加入输出数组的情况,然而忽略了流向一条S->T的流有多个边权=0的情况,此时只增大一条边的值是没用的。
所以除了用一次最大流算法后,还需要用两次dfs分别从超级源点S和汇点T开始搜索,这样就可以把有多个0-0-0和单个边权为0的情况判断出来。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef struct node
{
int u;
int v;
int Flow;
int next;
}Line;
Line Li[];
int Head[],top;
int vis[],ans[];
bool vis1[],vis2[];
int n,m,l;
int s,t;
void AddEdge(int u,int v,int f)
{
Li[top].v=v; Li[top].u=u;
Li[top].Flow=f;
Li[top].next=Head[u];
Head[u]=top++;
}
bool BFS()
{
memset(vis,-,sizeof(vis));
vis[s]=;
queue<int >Q;
Q.push(s);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
for(int i=Head[u];i!=-;i=Li[i].next)
{
if(Li[i].Flow&&vis[Li[i].v]==-)
{
vis[Li[i].v]=vis[u]+;
Q.push(Li[i].v);
}
}
}
return vis[t]!=-;
}
int DFS(int u,int f)
{
if(u==t)
{
return f;
}
int ans=;
for(int i=Head[u];i!=-;i=Li[i].next)
{
if(Li[i].Flow&&vis[Li[i].v]==vis[u]+)
{
int d=DFS(Li[i].v,min(f,Li[i].Flow));
f-=d;
Li[i].Flow-=d;
Li[i^].Flow+=d;
ans+=d;
}
}
return ans;
}
void dfs(int u,bool *vist,int op)
{
vist[u]=true;
for(int i=Head[u];i!=-;i=Li[i].next)
{
if(!vist[Li[i].v]&&Li[i^op].Flow!=)
{
dfs(Li[i].v,vist,op);
}
}
}
void Dinic()//网络流进行增广
{
int ans;
while(BFS())
{
ans=DFS(s,INF);
printf("!\n");
}
}
int main()
{
while(~scanf("%d %d %d",&n,&m,&l))
{
if(n+m+l==)
{
break;
}
s=n+m+;//源点
t=;//汇点
memset(Head,-,sizeof(Head));
int a,b,c;
top = ;
for(int i=;i<l;i++)
{
scanf("%d %d %d",&a,&b,&c);
AddEdge(a,b,c);//建立边,正向为c,负向为0
AddEdge(b,a,);
}
for(int i=;i<=n;i++)
{
AddEdge(s,i,INF);
AddEdge(i,s,);//建立城市与源点之间的边,权值为INF
}
Dinic();
memset(vis1,false,sizeof(vis1));
memset(vis2,false,sizeof(vis2));
dfs(s,vis1,);//从源点向汇点搜索,标记还有剩余流的点
dfs(t,vis2,);//从汇点到源点搜索,标记还有剩余流的点
int num=;
for(int i=;i<l;i++)
{
if(Li[i<<].Flow==&&vis1[Li[i<<].u]&&vis2[Li[i<<].v])
ans[num++]=i+;//如果一条边的u与v都被标记,表明s->u,v->t,但是这条边是满流,所以提升这条边。
}
if(num)
{
for(int i=;i<num;i++)
{
if(i)printf(" ");
printf("%d",ans[i]);
}
}
printf("\n");
}
return ;
}
代码转自(https://blog.csdn.net/huayunhualuo/article/details/50554800)这个题解的板子跟我的差不多就转了
ZOJ 2532 网络流最小割的更多相关文章
- 【题解】 bzoj3894: 文理分科 (网络流/最小割)
bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...
- 【bzoj3774】最优选择 网络流最小割
题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...
- 【bzoj1143】[CTSC2008]祭祀river Floyd+网络流最小割
题目描述 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成的网络.每条河 ...
- 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan
题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...
- 【bzoj1976】[BeiJing2010组队]能量魔方 Cube 网络流最小割
题目描述 一个n*n*n的立方体,每个位置为0或1.有些位置已经确定,还有一些需要待填入.问最后可以得到的 相邻且填入的数不同的点对 的数目最大. 输入 第一行包含一个数N,表示魔方的大小. 接下来 ...
- 【bzoj4177】Mike的农场 网络流最小割
题目描述 Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中第i个牲畜围栏中的动物长大后,每只牛可以卖a[i] ...
- 【bzoj3438】小M的作物 网络流最小割
原文地址:http://www.cnblogs.com/GXZlegend/p/6801522.html 题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物 ...
- 【bzoj3144】[Hnoi2013]切糕 网络流最小割
题目描述 输入 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤ ...
- 【bzoj3894】文理分科 网络流最小割
原文地址:http://www.cnblogs.com/GXZlegend 题目描述 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用 ...
随机推荐
- springBoot 使用redis 和 StringRedisTemplate 常用操作
spring boot 使用 redis : 1,pom 引入 redis,貌似springboot 1.5以上的版本,引入redis必须加 <version></version&g ...
- 关于mysql一边查一边更新
update test_table set user_id = 112 where id in (select id from ( select id from test_table where nu ...
- 基于Wiki的知识共享平台模型架构
一.引言 当今的全球化知识经济社会中呈现出信息泛滥和知识更新周期短的现象,知识管理逐渐成为现代企业管理中不容忽视的一环.虚拟企业是基于共识目标而组成的动态协作组织,成员参与的流动性与各成员之间地域分布 ...
- markdown 的一些字体
<font face='Comic Sans MS', size=5> 看看字体 1 one Hello 2 two Hello <font face='Kristen ITC', ...
- The sequence and de novo assembly of the giant panda genome.ppt
sequencing:使用二代测序原因:高通量,短序列 不用长序列原因: 1.算法错误率高 2.长序列测序将嵌合体基因错误积累.嵌合体基因:通过重组由来源与功能不同的基因序列剪接而形成的杂合基因 se ...
- 自定义控件 监控宿主activity的生命周期
使用不显示的fragment来监控activity生命周期,fragment生命周期基本上跟随宿主activity变化.我们通过fragment的生命周期就可以知到activity的生命周期 我们自定 ...
- vue实现动态绑定class--(三目运算符)根据span数字内容改变其样式
一.根据span数字内容改变数字本身样式(两种样式) <template> //使用三目运算符,判断当span的val是否小于0给其不同的class名 <span class=&qu ...
- 跨域问题与SpringBoot解决方案
什么是跨域? 定义:浏览器从一个域名的网页取请求另一个域名下的东西.通俗点说,浏览器直接从A域访问B域中的资源是不被允许的,如果想要访问,就需要进行一步操作,这操作就叫"跨域".例 ...
- shell、cmd、dos和脚本语言
问题一:Shell是什么? 操作系统可以分成核心(kernel)和Shell(外壳)两部分,其中,Shell是操作系统与外部的主要接口,位于操作系统的外层,为用户提供与操作系统核心沟通的途径.Shel ...
- UML Learning
在建筑业中,建模是一项经过检验并被广泛接受的工程技术,建立房屋和大厦的建筑模型,能帮助用户得到实际建筑物的印象.在软件建模中也具有同样的作用,建模提供了系统的蓝图. 建模是为了能够更好地理解正在开发的 ...