1. 程式人生 > >BZOJ 2929--洞穴攀行(最大流)

BZOJ 2929--洞穴攀行(最大流)

ans getchar() bool target 起點 insert 模版 mem ast

    最大流模版題。。。

題目鏈接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=2929

Solution

    與起點或終點連接的邊流量可以無限大,其他邊流量最大為1,求最大流。。。

    上模版就好了。。。。

代碼

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define inf 1000000000
using namespace std;
inline int read(){
    int x=0;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)ch=getchar();
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x;
}
int n,cnt=1,ans;
int h[205],q[205],last[205],cur[205];
struct edge{
    int to,next,v;
}e[40005];
void insert(int u,int v,int w){
    e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
    e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=0;
}
bool bfs(){
    int head=0,tail=1;
    memset(h,-1,sizeof(h));
    h[1]=0;
    q[0]=1;
    while(head!=tail){
        int now=q[head];head++;
        for(int i=last[now];i;i=e[i].next)
            if(e[i].v&&h[e[i].to]==-1){
                h[e[i].to]=h[now]+1;
                q[tail++]=e[i].to;
            }
    }
    return h[n]!=-1;
}
int dfs(int x,int f){
    if(x==n)return f;
    int w,used=0;
    for(int i=last[x];i;i=e[i].next)
        if(h[x]+1==h[e[i].to]){
            w=f-used;
            w=dfs(e[i].to,min(e[i].v,w));
            e[i].v-=w;e[i^1].v+=w;
            used+=w;
            if(used==f)return f;
        }
    if(!used)h[x]=-1;
    return used;
}
void dinic(){
    while(bfs())
        ans+=dfs(1,inf);
}
int main(){
    n=read();
    int x;
    for(int i=1;i<n;i++){
        x=read();
        while(x--){
            int v=read();
            if(i==1||v==n)insert(i,v,1);
            else insert(i,v,inf);
        }
    }
    dinic();
    printf("%d",ans);
    return 0;
}

  

  

This passage is made by Iscream-2001.

BZOJ 2929--洞穴攀行(最大流)