zoukankan      html  css  js  c++  java
  • bzoj2502: 清理雪道(有源汇有上下界最小流)

    传送门

    别说话,自己看,我不会->这里

    我这里用的建图方法是先跑一次最大流,连上$(t,s,inf)$之后再跑一遍,然后答案就是之前连的那条边的反向边的流量

    据说还有种方法是连上$(t,s,inf)$之后跑一遍,记录这条边反向边流量,再拆掉边以及$ss$和$tt$,然后再跑一次最大流,答案就是之前记录的流量减去这次的流量。亲测差不多

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #define inf 0x3f3f3f3f
     7 using namespace std;
     8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     9 char buf[1<<21],*p1=buf,*p2=buf;
    10 inline int read(){
    11     #define num ch-'0'
    12     char ch;bool flag=0;int res;
    13     while(!isdigit(ch=getc()))
    14     (ch=='-')&&(flag=true);
    15     for(res=num;isdigit(ch=getc());res=res*10+num);
    16     (flag)&&(res=-res);
    17     #undef num
    18     return res;
    19 }
    20 const int N=505,M=100005;
    21 int head[N],Next[M],ver[M],edge[M],tot=1;
    22 int cur[N],dep[N],S,T;
    23 queue<int> q;
    24 inline void add(int u,int v,int e){
    25     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
    26     ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0;
    27 }
    28 bool bfs(){
    29     memset(dep,-1,sizeof(dep));
    30     memcpy(cur,head,sizeof(head));
    31     while(!q.empty()) q.pop();
    32     q.push(S),dep[S]=0;
    33     while(!q.empty()){
    34         int u=q.front();q.pop();
    35         for(int i=head[u];i;i=Next[i]){
    36             int v=ver[i];
    37             if(dep[v]<0&&edge[i]){
    38                 dep[v]=dep[u]+1,q.push(v);
    39                 if(v==T) return true;
    40             }
    41         }
    42     }
    43     return false;
    44 }
    45 int dfs(int u,int limit){
    46     if(u==T||!limit) return limit;
    47     int flow=0,f;
    48     for(int i=cur[u];i;cur[u]=i=Next[i]){
    49         int v=ver[i];
    50         if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){
    51             flow+=f,limit-=f;
    52             edge[i]-=f,edge[i^1]+=f;
    53             if(!limit) break;
    54         }
    55     }
    56     if(!flow) dep[u]=-1;
    57     return flow;
    58 }
    59 int dinic(){
    60     int flow=0;
    61     while(bfs()) flow+=dfs(S,inf);
    62     return flow;
    63 }
    64 int n,s,t,k[N];
    65 int main(){
    66     //freopen("testdata.in","r",stdin);
    67     n=read();
    68     for(int i=1;i<=n;++i){
    69         int x=read();
    70         while(x--){
    71             int y=read();
    72             --k[i],++k[y];
    73             add(i,y,inf);
    74         }
    75     }
    76     s=0,t=n+1,S=n+2,T=n+3;
    77     for(int i=1;i<=n;++i)
    78     add(s,i,inf),add(i,t,inf);
    79     for(int i=1;i<=n;++i)
    80     k[i]<0?add(i,T,-k[i]):add(S,i,k[i]);
    81     dinic();
    82     add(t,s,inf);
    83     dinic();
    84     printf("%d
    ",edge[tot]);
    85     return 0;
    86 }
  • 相关阅读:
    hdu1240 bfs 水题
    hdu 2102 BFS
    gym 101081E Polish Fortress 几何
    Gym 101081K Pope's work dp
    hdu 6188 贪心
    hdu 6186 水
    Codeforces Round #430 (Div. 2) A B 水 C dfs,思维 D trie,二进制
    hdu6152 拉姆齐定理
    hdu6165 缩点,dfs
    hdu6153 扩展KMP
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9584569.html
Copyright © 2011-2022 走看看