zoukankan      html  css  js  c++  java
  • 网络流小结+[jzyzoj p1320] patrol

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

    ↑虽然不是我写的但是观摩一下总是没问题的嗯
     
    看到晗神学的是神奇的ek算法.
    但是看起来还是Ford-Fulkerson比较简单..所以我就学了这个...嗯其他的先看看..这个似乎比较好上手....
     
    从题目要求来看,我们只需要建一个双向图,然后用神奇的网络流算法算出到终点的最大流量-1即可 ( 因为留一条路出来就可以满足来回不能只经过每个土地1次或者0次 )
     但是并不对
     
    网络流小结+[jzyzoj p1320] patrol - 拟南芥 - 鲸头鹳
     
    如上为本题某数据 ( 好像是in3 ) 的建图[我知道我画的很丑],所示从1到7的流为2,但是放狗数为0,说明这个建图太naive了,报道出了偏差;
    很明显,这个建法错误的原因是点4被经过了两次,但是事实上每个点只能经过一次,普通的建图并不能完成这个要求;
    我们需要的是限制每个点的流量,那么我们把每个点变成流量为1的边 参考晗神博客 )如下图
    网络流小结+[jzyzoj p1320] patrol - 拟南芥 - 鲸头鹳
     
    (少写一个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
    ",ans);
    90     }
    91     else
    92         printf("%d
    ",ans-1);
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    c ++ auto 的使用
    poj 3169 Layout
    1076 Forwards on Weibo (30)(30 分)
    Zookeeper注册节点的掉线自动重新注册及测试方法
    ZooKeeper(3.4.5) 使用Curator监听事件
    Nginx 引入线程池,提升 9 倍性能
    面试总结 地址
    struts2原理
    struts2拦截器与过滤器
    java网络编程serversocket
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7783833.html
Copyright © 2011-2022 走看看