luogu P1344 [USACO4.4]追查坏牛奶Pollutant Control

传送门

要求断掉某些边使得两个点不连通,显然是最小割

但是要求选的边数尽量少,,,

可以考虑修改边权(容量),即把边权\(c\)改成\(c*(m+1)+1\)

没了

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define inf (1ll<<60)

using namespace std;
const int N=40,M=1000+10;
il LL rd()
{
    re LL x=0,w=1;re char ch=0;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int to[M<<1],nt[M<<1],hd[N],tot=1;
LL c[M<<1],sum;
il void add(int x,int y,LL z)
{
  ++tot,to[tot]=y,nt[tot]=hd[x],c[tot]=z,hd[x]=tot;
  ++tot,to[tot]=x,nt[tot]=hd[y],c[tot]=0,hd[y]=tot;
}
int n,m,ss,tt;
int lv[N];
bool v[N];
il bool bfs()
{
  memset(lv,63,sizeof(lv));
  lv[ss]=0;
  queue<int> q;
  q.push(ss),v[ss]=true;
  while(!q.empty())
    {
      int x=q.front();
      q.pop();
      for(int i=hd[x];i;i=nt[i])
        {
          int y=to[i];
          if(c[i]>0&&lv[y]>lv[x]+1)
            {
              lv[y]=lv[x]+1;
              if(!v[y]) q.push(y);
              v[y]=true;
            }
        }
      v[x]=false;
    }
  return lv[tt]<lv[tt+1];
}
LL dfs(int x,LL ff)
{
  if(x==tt) return ff;
  LL su=0;
  for(int i=hd[x];i&&ff>0;i=nt[i])
    {
      int y=to[i];
      if(c[i]>0&&lv[y]==lv[x]+1)
        {
          LL dlt=dfs(y,min(ff,c[i]));
          su+=dlt,ff-=dlt;
          c[i]-=dlt,c[i^1]+=dlt;
        }
    }
  if(!su) lv[x]=0;
  return su;
}

int main()
{
  n=rd(),m=rd();
  ss=1,tt=n;
  for(int i=1;i<=m;i++)
    {
      int x=rd(),y=rd(),z=1ll*rd()*1001+1;
      add(x,y,z);
    }
  while(bfs())
    sum+=dfs(ss,inf);
  printf("%lld %lld\n",sum/1001,sum%1001);
  return 0;
}

posted @ 2018-09-25 22:06  ✡smy✡  阅读(90)  评论(0编辑  收藏  举报