Peng Lv

毋意,毋必,毋固,毋我。 言必行,行必果。

导航

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;
}

 

 

posted on 2010-02-03 16:10  Lvpengms  阅读(693)  评论(0编辑  收藏  举报