最大流(邻接表实现)

这是来自zjut-vegetable的好东西~~收藏下,邻接表是个好东西!

 

#include < iostream >
using   namespace  std;
const   int  maxn = 205 ;
const   int  inf = 1000000000 ;
int  pre[maxn],que[maxn],d[maxn],v[maxn];
struct  node
{
    
int  v,val,next;
}s[
505 ];
int  flow[ 505 ];
int  p[ 205 ];
int  ind;
int  id[ 505 ];
int  maxflow( int  source, int  sink)
{
    
int  h,r,ret = 0 ,i,j,k;
    memset(flow,
0 , sizeof (flow));
    
for (;;)
    {
        memset(v,
0 , sizeof (v));
        memset(d,
0 , sizeof (d));
        que[
0 ] = source;
        v[source]
= 1 ;
        d[source]
= inf;
        h
= r = 0 ;
        
while (h <= &&! v[sink])
        {
            k
= que[h ++ ];
            
for ( int  q = p[k];q !=- 1 ;q = s[q].next)
            {
                i
= s[q].v;
                
if ( ! v[i] && flow[q] < s[q].val)
                {
                    v[i]
= 1 ;
                    que[
++ r] = i;
                    pre[i]
= k;
                    id[i]
= q;
                    d[i]
= min(s[q].val - flow[q],d[k]);
                }
            }
        }
        
if ( ! v[sink]) break ;
        ret
+= d[sink];
        
for (i = sink;i != source;)
        {
            j
= i;
            i
= pre[i];
            flow[id[j]]
+= d[sink];
            k
= id[j];
            
if (k < ind)
                k
+= ind;
            
else
                k
-= ind;
            flow[k]
=- flow[id[j]];
        }
    }
    
return  ret;
}
int  main()
{
    
int  m,n;
    
while (cin >> m >> n)
    {
        
int  x,y,z;
        memset(p,
- 1 , sizeof (p));
        ind
= m;
        
for ( int  i = 0 ;i < m;i ++ )
        {
            cin
>> x >> y >> z;
            s[i].v
= y;
            s[i].next
= p[x];
            s[i].val
= z;
            p[x]
= i;
            s[i
+ m].v = x;
            s[i
+ m].next = p[y];
            s[i
+ m].val = 0 ;
            p[y]
= i + m;
        }
        cout
<< maxflow( 1 ,n) << endl;
    }
}

转载于:https://www.cnblogs.com/zhuangli/archive/2008/08/03/1259153.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值