• 网络流小结+[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
  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7783833.html
Copyright © 2020-2023  润新知