网络流小结+[jzyzoj p1320] patrol

一个不能更清楚的网络流介绍

↑虽然不是我写的但是观摩一下总是没问题的嗯

看到晗神学的是神奇的ek算法.

但是看起来还是Ford-Fulkerson比较简单..所以我就学了这个...嗯其他的先看看..这个似乎比较好上手....

从题目要求来看,我们只需要建一个双向图,然后用神奇的网络流算法算出到终点的最大流量-1即可 ( 因为留一条路出来就可以满足来回不能只经过每个土地1次或者0次 )

但是并不对

如上为本题某数据 ( 好像是in3 ) 的建图[我知道我画的很丑],所示从1到7的流为2,但是放狗数为0,说明这个建图太naive了,报道出了偏差;

很明显,这个建法错误的原因是点4被经过了两次,但是事实上每个点只能经过一次,普通的建图并不能完成这个要求;

我们需要的是限制每个点的流量,那么我们把每个点变成流量为1的边 参考晗神博客 )如下图

(少写一个4假装没看见好了,最后的7看起来很像1就像吧..)

这些点i与i+n相连的边,边权都为1,这样就做到了每个"点"经过一次,起点和终点不需要流量限制所以注意特判

所以最恶心的是为什么我完全没考虑每个点的流量就能写90分???????滔天的水扑面而来啊摔

顺便存一个丑代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdlib>
 7 using namespace std;
 8 const int minf=2100010000;
 9 int n,m;
10 struct nod{
11     int rev;
12     int y;
13     int next;
14     int v;
15 }e[201010];
16 int head[2100]={};
17 int tot=0;
18 bool vis[2100]={};
19 inline void init(int x,int y,int v,int rev){
20     e[++tot].y=y;
21     e[tot].next=head[x];
22     e[tot].v=v;
23     e[tot].rev=rev;
24     head[x]=tot;
25 }
26 inline int dis(int x){
27     return x+n;
28 }
29 int dfs(int s,int t,int f){
30     if(s==t){
31         return f;
32     }
33     vis[s]=1;
34     for(int i=head[s];i;i=e[i].next){
35         int v=e[i].v,y=e[i].y;
36         if(vis[y]==0&&v>0){
37             int d=dfs(y,t,min(f,v));
38             if(d>0){
39                 e[i].v-=d;
40                 e[e[i].rev].v+=d;
41                 return d;
42             }
43         }
44     }
45     return 0;
46 }
47 int main(){
48     //freopen("wtf.in","r",stdin);
49     scanf("%d%d",&n,&m);
50     int x,y;
51     for(int i=2;i<n;i++){
52         init(i,i+n,1,tot+2);
53         init(i+n,i,1,tot);
54     }
55     for(int i=1;i<=m;i++){
56         scanf("%d%d",&x,&y);
57         if(x>y){
58             swap(x,y);
59         }
60         if(y==n){
61             init(x+n,y,1,tot+2);
62             init(y,x+n,0,tot);
63             init(y,x+n,1,tot+2);
64             init(x+n,y,0,tot);
65         }
66         else if(x==1){
67             init(1,y,1,tot+2);
68             init(y,1,0,tot);
69             init(y,1,1,tot+2);
70             init(1,y,0,tot);
71         }
72         else{
73             init(x+n,y,1,tot+2);
74             init(y,x+n,0,tot);
75             init(y+n,x,1,tot+2);
76             init(x,y+n,0,tot);
77         }
78     }
79     int ans=0;
80     for(;;){
81         memset(vis,0,sizeof(vis));
82         int f=dfs(1,n,minf);
83         if(f==0){
84             break;
85         }
86         ans+=f;
87     }
88     if(ans==0){
89         printf("%d\n",ans);
90     }
91     else
92         printf("%d\n",ans-1);
93     return 0;
94 }

时间: 2024-08-11 16:45:14

网络流小结+[jzyzoj p1320] patrol的相关文章

【jzyzoj】【p1320 patrol】 巡逻(网络流最小割例题)

描述 Description FJ有个农场,其中有n块土地,由m条边连起来.FJ的养牛场在土地1,在土地n有个新开张的雪糕店.Bessie经常偷偷溜到雪糕店,当Bessie去的时候,FJ就要跟上她.但是Bessie很聪明,她在从雪糕店返回时不会经过去雪糕店时经过的农场,因此FJ总是抓不住Bessie.为了防止Bessie生病,FJ决定把一些诚实的狗放在一些土地(1和n除外)上,使Bessie无法在满足每块土地最多只经过一次的条件的情况下,从养牛场溜到雪糕店然后又溜回养牛场.求出FJ最少要放多少只

网络流小结

这两天复习了下网络流,高中学的ISAP忘得七七八八,干脆把Dinic,ISAP和预流推进都重新看了一遍,写了个简洁的小结(基本上就是给自己看的) 网络流 剩余图 顶点的层次:源点到点的最短路径长度 层次图建立在剩余图基础上 阻塞流:不存在增广路时 FF 复杂度O(n*m*u) 容量网络.流量网络.残量网络 用最大流最小割定理证明 EK 复杂度O(n*m*m) 建反向边,每次bfs找最短增广路 最多增广n*m次(每阶段最多增广m次) Dinic 多路增广 1.初始化容量网络和网络流 2.构造残留网

上下界网络流小结

虽然网上已经有很详细的解释了,但是别人总结的终究是别人的. 1无源无汇上下界的可行流 首先明确定义:B[u, v]和C[u, v]表示边(u,v)的下界容量和上界容量,我们的问题是求一个每条边都具有上下界的可行流. 简单分析:由于每条边要满足下界容量,而且每个点要满足流量平衡,所以就需要对平时的网络流模型改造. 方法一:建立附加远点回电,S,T,对于边(u, v),连边S->v,容量B[u, v], 及u->T, 容量B[u, v], 然后对于本来的边u->v,容量改为C[u, v]-B

(转)一句话小结各种网络流)

最大流:DINIC or SAP 最小费用最大流:SPFA+增广(费用的值较离散) or ZKW(费用的值集中) 有源汇的上下界最大流:新建s', t',用(i, j, l, r)表示i到j有一条下界为l上界为r的边,将每条这样的边拆成(s', j, 0, l), (i, t', 0, l), (i, j, 0, r-l),加入边(t, s, 0, max)再从s‘到t'求最大流,再去掉(t, s, 0, max)这条边,从s到t求最大流 有源汇的上下界最小可行流:基本同上,将最后一步改成从t到

小结:网络流

概要: 这货很强大啊.isap和dinic都算很快的算法,目前貌似卡不了?spfa在费用流中找增广路.上下界的网络流可以用分离必要弧来做. 应用: 解决许多多约束最优化的问题. 技巧及注意: 网络流在于建模,但是首先得有个基础. 上下界网络流:整体思想就是分离下界,将原边连成上界-下界,终点的界和+=这个下界,起点的界和-=这个下界.处理完后,然后扫这些点,如果界和大于0,附加源连这个点容量为界和,反之连到附加汇容量为界和绝对值.具体看有上下界的网络流问题.

BZOJ 1497 JZYZOJ 1344 [NOI2006]最大获利 网络流 最大权闭合图

http://www.lydsy.com/JudgeOnline/problem.php?id=1497 http://172.20.6.3/Problem_Show.asp?id=1344 思路:(最大权闭合图的思路相同) 将所有的用户群获利(正值)作为一个点连一条权值为获利值的边到st点,将所有的建站消耗(输入的是正值但是是在获利中减去的所以实质还是负值)作为一个点连一条权值为消耗值的边到ed点,再将每个用户群点和其依赖的建站点连一条权值为无穷的边,求st到ed的最大流. 此时,所求的最大获

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

图论专题小结:网络流算法之ISAP算法

ISAP算法 ISAP(Improved Shortest Augument Path)算法是改进版的SAP算法,如果对效率要求很高的时候,可以用该算法. (1)概述:算法基于这样的一个事实:每次增广之后,任意结点到汇点(在残余网络中)的最短距离都不会减小.这样,我们可以利用d[i[表示结点i到汇点的距离的下界.然后再增广过程当中不断地修改这个下界.增广的时候和Dinic算法类似,只允许沿着d[i]==d[j]+1的弧(i,j)走. 不难证明,d[i[满足两个条件:(1)d[t]=0;(2)对任

欧拉路,欧拉回路小结(转)

欧拉路,欧拉回路小结 把欧拉路和欧拉回路做一个小总结,包含了一些题目,以后遇到新的我还会陆续加上. 定义: 给定无孤立结点图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在 一条回路经过G每条边有且仅有一次,称这条回路为欧拉回路.具有欧拉回路的图成为欧拉图. 关于欧拉路和欧拉回路定义及存在证明请看这里. 这里给出欧拉路和欧拉回路存在条件的结论: 存在欧拉路的条件: 无向图:  图连通,所有点都是偶数度,或者只有两个点是奇数度.当所有点是偶数度时欧拉路起点可以是任意 点:当