【题解】Luogu P1344 [USACO4.4]追查坏牛奶Pollutant Control

原题传送门

看到这种题,应该一眼就能知道考的是最小割

没错这题就是如此简单,跑两遍最大流(最小割=最大流),一次边权为题目所给,一次边权为1

还有一种优化,优化后只需跑一次最大流,把每条边的权值改成w*MOD+1(MOD为常数,珂以取八位质数233)

答案为maxflow/MOD和maxflow%MOD

基础版本

#include <bits/stdc++.h>
#define N 40
#define M 2005
#define inf 0x3f3f3f3f
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline int Min(register int a,register int b)
{
    return a<b?a:b;
}
struct edge{
    int to,nxt,v;
}e[M];
int head[N],cnt=1;
inline void add(register int u,register int v,register int w)
{
    e[++cnt]=(edge){v,head[u],w};
    head[u]=cnt;
}
int n,m,s,t,maxflow=0;
int cur[N],dep[N],gap[N];
inline void bfs()
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    dep[t]=0;
    ++gap[dep[t]];
    queue <int> q;
    q.push(t);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(register int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].to;
            if(dep[v]!=-1)
                continue;
            q.push(v);
            dep[v]=dep[u]+1;
            ++gap[dep[v]];
        }
    }
}
inline int dfs(register int u,register int flow)
{
    if(u==t)
    {
        maxflow+=flow;
        return flow;
    }
    int used=0;
    for(register int i=cur[u];i;i=e[i].nxt)
    {
        cur[u]=i;
        int v=e[i].to;
        if(e[i].v&&dep[u]==dep[v]+1)
        {
            int tmp=dfs(v,Min(flow-used,e[i].v));
            if(tmp)
                e[i].v-=tmp,e[i^1].v+=tmp,used+=tmp;
        }
        if(used==flow)
            return used;
    }
    --gap[dep[u]++]==0?dep[s]=n+1:++gap[dep[u]];
    return used;
}
inline void ISAP()
{
    maxflow=0;
    bfs();
    while(dep[s]<=n)
    {
        memcpy(cur,head,sizeof(head));
        dfs(s,inf);
    }
}
int main()
{
    n=read(),m=read();
    s=1,t=n;
    for(register int i=1;i<=m;++i)
    {
        int u=read(),v=read(),w=read();
        add(u,v,w),add(v,u,0);
    }
    ISAP();
    write(maxflow),putchar(' ');
    for(register int i=2;i<=cnt;++i)
        e[i].v=i%2?0:1;
    ISAP();
    write(maxflow);
    return 0;
}

优化版本

#include <bits/stdc++.h>
#define N 40
#define M 2005
#define inf 123456789123456789LL 
#define ll long long 
#define mod 19260817LL
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline ll read()
{
    register ll x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register ll x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline ll Min(register ll a,register ll b)
{
    return a<b?a:b;
}
struct edge{
    int to,nxt;
    ll v;
}e[M];
int head[N],cnt=1;
inline void add(register int u,register int v,register ll w)
{
    e[++cnt]=(edge){v,head[u],w};
    head[u]=cnt;
}
int n,m,s,t;
ll maxflow=0;
int cur[N],dep[N],gap[N];
inline void bfs()
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    dep[t]=0;
    ++gap[dep[t]];
    queue <int> q;
    q.push(t);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(register int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].to;
            if(dep[v]!=-1)
                continue;
            q.push(v);
            dep[v]=dep[u]+1;
            ++gap[dep[v]];
        }
    }
}
inline ll dfs(register int u,register ll flow)
{
    if(u==t)
    {
        maxflow+=flow;
        return flow;
    }
    ll used=0;
    for(register int i=cur[u];i;i=e[i].nxt)
    {
        cur[u]=i;
        int v=e[i].to;
        if(e[i].v&&dep[u]==dep[v]+1)
        {
            ll tmp=dfs(v,Min(flow-used,e[i].v));
            if(tmp)
                e[i].v-=tmp,e[i^1].v+=tmp,used+=tmp;
        }
        if(used==flow)
            return used;
    }
    --gap[dep[u]++]==0?dep[s]=n+1:++gap[dep[u]];
    return used;
}
inline void ISAP()
{
    maxflow=0;
    bfs();
    while(dep[s]<n)
    {
        memcpy(cur,head,sizeof(head));
        dfs(s,inf);
    }
}
int main()
{
    n=read(),m=read();
    s=1,t=n;
    for(register int i=1;i<=m;++i)
    {
        int u=read(),v=read(),w=read();
        add(u,v,w*mod+1),add(v,u,0);
    }
    ISAP();
    write(maxflow/mod),putchar(' '),write(maxflow%mod);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/yzhang-rp-inf/p/10357244.html