POJ 3469 dual core cpu ---ISAP

/*这个题目的构图还是不错的,关键是最大流最小割定理的理解程度,算法用的是ISAP,效率还不错。 需要注意的是比如这句话 edge[index].pair = ++index,不同的编译器对这句话的翻译是不一样的, 主要是对++index的处理,有的是先对++index处理:++index,edge[index].pair = index,而有的不是, 可能翻译成:edge[index].pair = index + 1;++index,就是在这个地方WA了好几次,这种错误真是太难检查 了、、、、归根结蒂还是自己对语言了解部透彻,编码习惯不太好。。。。*/

 

#include  < iostream >
#include 
< cstdio >
#include 
< memory.h >
using   namespace  std;

#define  MAXN 30020
#define  MAXE 2000000
#define  INF 0x3fffffff

int  ne,nv,index,s,t,net[MAXN];
struct  Edge{
    
int  next,pair;
    
int  v,cap,flow;
}edge[MAXE];
void  add( const   int &  u, const   int &  v, const   int &  val)
{
    edge[index].next 
=  net[u];
    net[u] 
=  index;
    edge[index].v 
=  v;
    edge[index].cap 
=  val;
    edge[index].flow 
=   0 ;
    edge[index].pair 
=  index + 1 ;
    
++ index;
    edge[index].next 
=  net[v];
    net[v] 
=  index; 
    edge[index].v 
=  u;
    edge[index].cap 
=   0 ;
    edge[index].flow 
=   0 ;
    edge[index].pair 
=  index  -   1 ;
    
++ index;
}
int  ISAP()
{
    
long  numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];
    
long  cur_flow,max_flow,u,tmp,neck,i;
    memset(dist,
0 , sizeof (dist));
    memset(numb,
0 , sizeof (numb));
    
for (i  =   1  ; i  <=  nv ;  ++ i)
        curedge[i] 
=  net[i];
    numb[nv] 
=  nv;
    max_flow 
=   0 ;
    u 
=  s;
    
while (dist[s]  <  nv)
    {
        
/*  first , check if has augmemt flow  */
        
if (u  ==  t)
        {
            cur_flow 
=  INF;
            
for (i  =  s; i  !=  t;i  =  edge[curedge[i]].v) 
            {  
                
if (cur_flow  >  edge[curedge[i]].cap)
                {
                    neck 
=  i;
                    cur_flow 
=  edge[curedge[i]].cap;
                }
            }
            
for (i  =  s; i  !=  t; i  =  edge[curedge[i]].v)
            {
                tmp 
=  curedge[i];
                edge[tmp].cap 
-=  cur_flow;
                edge[tmp].flow 
+=  cur_flow;
                tmp 
=  edge[tmp].pair;
                edge[tmp].cap 
+=  cur_flow;
                edge[tmp].flow 
-=  cur_flow;
            }

            max_flow 
+=  cur_flow;
            u 
=  s;
        }
        
/*  if .... else ...  */
        
for (i  =  curedge[u]; i  !=   - 1 ; i  =  edge[i].next)
            
if (edge[i].cap  >   0   &&  dist[u]  ==  dist[edge[i].v] + 1 )
                
break ;
        
if (i  !=   - 1 )
        {
            curedge[u] 
=  i;
            pre[edge[i].v] 
=  u;
            u 
=  edge[i].v;
        }
else {
            
if ( 0   ==   -- numb[dist[u]])  break ;
            curedge[u] 
=  net[u];
            
for (tmp  =  nv,i  =  net[u]; i  !=   - 1 ; i  =  edge[i].next)
                
if (edge[i].cap  >   0 )
                    tmp 
=  tmp < dist[edge[i].v] ? tmp:dist[edge[i].v];
            dist[u] 
=  tmp  +   1 ;
            
++ numb[dist[u]];
            
if (u  !=  s) u  =  pre[u];
        }
    }
    
return  max_flow;
}
int  main()
{
    
int  n,m,i,j,val,a,b;
    index 
=   0 ;
    scanf(
" %d%d " , & n, & m);
    s 
=  n  +   1 ;
    t 
=  n  +   2 ;
    nv 
=  t;
    memset(net,
- 1 , sizeof (net));
    
for (i  =   1 ;i  <=  n;  ++ i)
    {
        scanf(
" %d%d " , & a, & b);
        add(s,i,a);
        add(i,t,b);
    }
    
for (i  =   1 ;i  <=  m;  ++ i)
    {
        scanf(
" %d%d%d " , & a, & b, & val);
        edge[index].next 
=  net[a];
        net[a] 
=  index;
        edge[index].v 
=  b;
        edge[index].cap 
=  val;
        edge[index].flow 
=   0 ;
        edge[index].pair 
=  index + 1 ;
        
++ index;
        edge[index].next 
=  net[b];
        net[b] 
=  index;
        edge[index].v 
=  a;
        edge[index].cap 
=  val;
        edge[index].flow 
=   0 ;
        edge[index].pair 
=  index  -   1 ;
        
++ index;
    }
    printf(
" %d\n " ,ISAP());
    
return   0 ;
}

 

 

你可能感兴趣的:(core)