洛谷 P1344 追查坏牛奶Pollutant Control —— 最小割

题目:https://www.luogu.org/problemnew/show/P1344

就是求最小割;

但是还要边数最小,所以把边权都*1001+1,这样原来流量部分是*1001,最大流一样的不影响,而+1会使其尽量减少边数;

bfs 里忘了给 dis[] 赋0了调了好半天...尴尬...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int const xn=35,xm=1005;
int n,m,hd[xn],ct=1,to[xm<<1],nxt[xm<<1],dis[xn],cur[xn];
ll ans,c[xm<<1],inf=1e12;
queue<int>q;
void add(int x,int y,ll cc)
{to[++ct]=y; nxt[ct]=hd[x]; c[ct]=cc; hd[x]=ct;}
int rd()
{
    int ret=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
    while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
    return f?ret:-ret;
}
bool bfs()
{
    while(q.size())q.pop();
    memset(dis,0,sizeof dis);//
    dis[1]=1; q.push(1);
    while(q.size())
    {
        int x=q.front(); q.pop();
        for(int i=hd[x],u;i;i=nxt[i])
            if(!dis[u=to[i]]&&c[i])dis[u]=dis[x]+1,q.push(u);
    }
    return dis[n];
}
ll dfs(int x,ll fl)
{
    if(x==n)return fl;
    ll ret=0;
    for(int &i=cur[x],u;i;i=nxt[i])
    {
        if(dis[u=to[i]]!=dis[x]+1||!c[i])continue;
        ll tmp=dfs(u,min(fl-ret,c[i]));
        if(!tmp)dis[u]=0;//
        c[i]-=tmp; c[i^1]+=tmp;
        ret+=tmp; if(ret==fl)return ret;//
    }
    return ret;
}
int main()
{
    n=rd(); m=rd();
    for(int i=1,x,y;i<=m;i++)
    {
        ll z;
        x=rd(); y=rd(); z=rd(); z=z*1001+1;
        add(x,y,z); add(y,x,0);
    }
    while(bfs())
    {
        memcpy(cur,hd,sizeof hd);
        ans+=dfs(1,inf);
    }
    printf("%lld %lld\n",ans/1001,ans%1001);
    return 0;
}

 

posted @ 2018-09-26 11:48  Zinn  阅读(143)  评论(0编辑  收藏  举报