luogu P1345 [USACO5.4]奶牛的电信Telecowmunication

https://www.luogu.org/problemnew/show/1345

 

拆点,中间建流量为1的边,跑最小割

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
std::queue<int>que;
#define INF 0x7fffffff
const int maxn = 10007;
inline int read() {
    int x=0;
    char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
    return x;
}
int n,m,S,T,src,decc;
struct node{
    int v,next,flow;
}edge[maxn>>1];int head[maxn],num=1,cur[maxn],lev[maxn];
void add_edge(int u,int v,int w) {
    edge[++num].v=v;edge[num].next=head[u];head[u]=num;
    edge[num].flow=w;
}
bool bfs() {
    while(!que.empty()) que.pop();
    std::memset(lev,-1,sizeof lev);
    memcpy(cur,head,sizeof head);  
    lev[src]=0;
    que.push(src);int now;
    while(!que.empty()) {
        now=que.front();que.pop();
        for(int i=head[now];i;i=edge[i].next) {
            int v=edge[i].v;
            if(lev[v]==-1&&edge[i].flow>0) {
                lev[v]=lev[now]+1;
                if(v==decc)return true;
                que.push(v);
            }
        }
    }
    return false;
}
int dfs(int now,int flow) {
    if(now==decc)return flow;
    int rest=0,delta;
    for(int &i=cur[now];i;i=edge[i].next) {
        int v=edge[i].v;
        if(lev[v]==lev[now]+1&&edge[i].flow>0) {
            delta=dfs(v,std::min(flow-rest,edge[i].flow));
            if(delta) {
                edge[i].flow-=delta;
                edge[i^1].flow+=delta;
                rest+=delta;if(rest==flow)break;
            }
        }
    }
    if(rest==flow)lev[now]=-1;//满流
    return rest;
}
int Dinic() {
    int ans=0;
    while(bfs()) 
        ans+=dfs(src,INF);
    return ans;
}
int main() {
    n=read(),m=read(),src=read(),decc=read();
    src+=n;
    for(int i=1;i<=n;++i) {
        add_edge(i,i+n,1);
        add_edge(i+n,i,0);
    }
    for(int a,b,i=1;i<=m;++i) {
        a=read(),b=read();
        add_edge(a+n,b,INF);
        add_edge(b,a+n,0);
        add_edge(b+n,a,INF);
        add_edge(a,b+n,0);
    }
    int ans=Dinic();
    printf("%d\n",ans);
    return 0;
}
    

 

posted @ 2017-12-23 20:03  zzzzx  阅读(250)  评论(0编辑  收藏  举报