poj3469 Dual Core CPU——最小割

题目:http://poj.org/problem?id=3469

最小割水题(竟然没能1A)

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int const maxn=2e4+5,maxm=2e5+5,inf=0x3f3f3f3f;
int n,m,hd[maxn],d[maxn],ct=1,cur[maxn],ans;
queue<int>q;
struct N{
    int to,nxt,w;
    N(int t=0,int n=0,int w=0):to(t),nxt(n),w(w) {}
}ed[(maxn+maxm)<<2];
void add(int x,int y,int z)
{
    ed[++ct]=N(y,hd[x],z); hd[x]=ct;
    ed[++ct]=N(x,hd[y],0); hd[y]=ct;
}
bool bfs()
{
    while(q.size())q.pop();
    memset(d,0,sizeof d);
    q.push(0); d[0]=1;
    while(q.size())
    {
        int x=q.front(); q.pop();
        for(int i=hd[x],u;i;i=ed[i].nxt)
            if(!d[u=ed[i].to]&&ed[i].w)d[u]=d[x]+1,q.push(u);
    }
    return d[n+1];
}
int dfs(int x,int f)
{
    if(x==n+1)return f;
    int res=0;
    for(int &i=cur[x],u;i;i=ed[i].nxt)
    {
        if(d[u=ed[i].to]==d[x]+1&&ed[i].w)
        {
            int k=dfs(u,min(ed[i].w,f-res));//f-res!!!
            res+=k; ed[i].w-=k; ed[i^1].w+=k;
            if(res==f)return f;
        }
    }
    if(!res)d[x]=0;
    return res;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,a,b;i<=n;i++)
    {
        scanf("%d%d",&a,&b);
        add(0,i,a); add(i,n+1,b);
    }
    for(int i=1,x,y,z;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z); add(y,x,z);
    }
    while(bfs())
    {
        memcpy(cur,hd,sizeof hd);
        ans+=dfs(0,inf);
    }
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Zinn/p/9280997.html
今日推荐