Section 4.2 ditch

来源:互联网 发布:知乎网站源码 编辑:程序博客网 时间:2024/06/05 05:01

/*
ID: niepeng1
PROG: ditch
LANG: C++
*/
#include<stdio.h>
#include<memory.h>
#define  min1(a,b) a<b?a:b
int flow[200][200],capa[200][200],pre[200],q[200];
int i,m,n;
bool Improvable()
{
 int s,e,i;
 memset(pre,-1,sizeof(pre));//标记所有节点未使用
 q[0]=0;pre[0]=0;s=e=0;
 while (s<=e)//
 {
  for (i=1;i<n;i++)
   if (pre[i]==-1&&(flow[q[s]][i]<capa[q[s]][i]||flow[i][q[s]]>0))
   {
    pre[i]=q[s];//标记该节点使用,即标记前一个节点
    e++;
    q[e]=i;//将该节点放入
    if (i==n-1) return true;//能到达终点
   }
  s++;//进行一轮广搜,跟我的方法区别。我的是深搜,第7个数据就超时了。不知道为什么,竟然会比我的快那么多,晕晕晕
 }
 return false;
}
void Increase()
{
 int now,min=0x7fffffff,t;
 now=n-1;
 while(now)
 {
  t=pre[now];//减小来的边的权值
  if (flow[t][now]<capa[t][now])
   min=min1(capa[t][now]-flow[t][now],min);
  else
   if (flow[now][t]>0)//流大于边的权值,说明有相反的边
    min=min1(flow[now][t],min);
  now=t;
 }
 now=n-1;
 while(now)
 {
  t=pre[now];//增加流的权值
  if (flow[t][now]<capa[t][now])
   flow[t][now]+=min;
  else//又有相反的边
   if (flow[now][t]>0)
    flow[now][t]-=min;
  now=t;
 }
}
int MaxFlow()
{
 int ret,i;
 while(Improvable()) 
  Increase();
 ret=0;
 for(i=1;i<n;i++)
  ret+=flow[0][i];
 return ret;
}
int main()
{
 freopen("ditch.in","r",stdin);
 freopen("ditch.out","w",stdout);
 int x,y,z;
 scanf("%d%d",&m,&n);
 memset(capa,0,sizeof(capa));
 for(i=0;i<m;i++){
  scanf("%d%d%d",&x,&y,&z);
  capa[x-1][y-1]+=z;
 }
 printf("%d/n",MaxFlow());
 return 0;
}

原创粉丝点击