poj 1459 Power Network

一道很果的最大流,需要自己建个超级源和超级汇

先是EKarp
756K 594MS 1373B
#include <iostream>
#include 
<cstdio>
#include 
<cstring>
#include 
<queue>

using namespace std;

const int N= 110;
int n;

int mat[N][N];

int EKarp(int s, int t)
{
    queue 
< int > que;
    
int flow[N][N], pre[N], temp[N], u, v, sum= 0;
    memset(flow, 
0 , sizeof(flow));
    
while (1)
    {
        que.push(s);
        memset(temp, 
0sizeof(temp));
        temp[s]
= 0x7fffffff;
        
while ( ! que.empty() )
        {
            u
= que.front();
            que.pop();
            
for ( v= 0 ; v < n+2 ; v++ )
                
if ( !temp[v] && mat[u][v] > flow[u][v] )
                {
                    que.push(v);
                    temp[v]
= temp[u] < mat[u][v]-flow[u][v] ? temp[u] : mat[u][v]-flow[u][v];
                    pre[v]
= u;
                }
        }
        
if ( temp[t] == 0 )
            
break;
        
for ( u = t ; u != s ; u=pre[u] )
        {
            flow[pre[u]][u] 
+= temp[t];
            flow[u][pre[u]] 
-= temp[t];
        }
        sum
+= temp[t];
    }
    
return sum;
}

int main()
{
    
while ( EOF != scanf("%d"&n) )
    {
        memset(mat, 
0sizeof(mat));
        
int i, source, user, nodes;
        scanf(
"%d%d%d"&source, &user, &nodes);
        
int s, e, t;
        
for ( i = 0 ; i < nodes ; i++ )
        {
            scanf(
"%*[^(](%d,%d)%d"&s, &e, &t);
            mat[s][e]
=t;
        }
        
for ( i = 0 ; i < source ; i++ )
        {
            scanf(
"%*[^(](%d)%d"&e, &t);
            mat[n][e]
= t;
        }
        
for ( i = 0 ; i < user ; i++ )
        {
            scanf(
"%*[^(](%d)%d"&s, &t);
            mat[s][n
+1]= t;
        }
        printf(
"%d\n", EKarp(n, n+1));
    }
    
return 0;
}
然后是STL队列的dinic
724K 79MS 1904B
#include <iostream>
#include 
<cstdio>
#include 
<cstring>
#include 
<queue>

using namespace std;

const int N= 110;
int n;

int mat[N][N];
int lev[N];
queue
<int> q;
int BFS(int s,int t)
{
    
int u,v;
    memset(lev,
-1,sizeof(lev));
    q.push(s);
    lev[s] 
= 0;
    
while!q.empty() )
    {
        u 
= q.front();
        q.pop();
        
for(v=0; v<=t; v++)
            
if( mat[u][v] > 0 && lev[v] == -1 )
            {
                lev[v] 
= lev[u] + 1;
                q.push(v);
            }
    }
    
return lev[t] != -1;
}
int Dinic(int s,int t)
{
    
int a[N],cur[N];
    
int pre[N];
    
int flow = 0;
    
int i,u,flag,v,ag,k;
    
while( BFS(s,t) )
    {
        
for(i=0; i<=t; i++)
        {
            cur[i] 
= 0;
            a[i] 
= 0x7fffffff;
        }
        u 
= s;
        
while(1)
        {
            flag 
= 0;
            
for(v=cur[u]; v<=t; v++)
                
if( mat[u][v] > 0 && lev[u] + 1 == lev[v] )
                {
                    flag 
= 1;
                    
break;
                }
            
if( flag )
            {
                cur[u] 
= v + 1;
                pre[v] 
= u;
                a[v] 
= mat[u][v];
                
if( a[v] > a[u] )
                    a[v] 
= a[u];
                u 
= v;
                
if( u == t )
                {
                    ag 
= a[t];
                    flow 
+= ag;
                    
for(v=t; v!=s; v=pre[v])
                    {
                        cur[pre[v]] 
= v;
                        mat[pre[v]][v] 
-= ag;
                        mat[v][pre[v]] 
+= ag;
                        a[v] 
-= ag;
                        
if( mat[pre[v]][v] == 0 )
                            u 
= pre[v];
                    }
                }
            }
            
else
                
if( u != s )
                {
                    lev[u] 
= 0x7fffffff;
                    u 
= pre[u];
                }
                
else    break;
        }
    }
    
return flow;
}

int main()
{
    
while ( EOF != scanf("%d"&n) )
    {
        memset(mat, 
0sizeof(mat));
        
int i, source, user, nodes;
        scanf(
"%d%d%d"&source, &user, &nodes);
        
int s, e, t;
        
for ( i = 0 ; i < nodes ; i++ )
        {
            scanf(
"%*[^(](%d,%d)%d"&s, &e, &t);
            mat[s][e]
=t;
        }
        
for ( i = 0 ; i < source ; i++ )
        {
            scanf(
"%*[^(](%d)%d"&e, &t);
            mat[n][e]
= t;
        }
        
for ( i = 0 ; i < user ; i++ )
        {
            scanf(
"%*[^(](%d)%d"&s, &t);
            mat[s][n
+1]= t;
        }
        printf(
"%d\n", Dinic(n, n+1));
    }
    
return 0;
}
最后是最强大的手写队列dinic
416K 63MS 1890B
#include <stdio.h>
#include 
<string.h>

const int N= 110;
const int MAX_QUE= 1<<15;
int n;
int mat[N][N];
int lev[N], que[MAX_QUE];
int BFS(int s,int t)
{
    
int u,v;
    
int front= 1, rear= 0;
    memset(lev,
-1,sizeof(lev));
    que[
0]= s;
    lev[s] 
= 0;
    
while( front > rear )
    {
        u 
= que[rear++];
        
for(v=0; v<=t; v++)
            
if( mat[u][v] > 0 && lev[v] == -1 )
            {
                lev[v] 
= lev[u] + 1;
                que[front
++]= v;
            }
    }
    
return lev[t] != -1;
}
int Dinic(int s,int t)
{
    
int a[N],cur[N];
    
int pre[N];
    
int flow = 0;
    
int i,u,flag,v,ag,k;
    
while( BFS(s,t) )
    {
        
for(i=0; i<=t; i++)
        {
            cur[i] 
= 0;
            a[i] 
= 0x7fffffff;
        }
        u 
= s;
        
while(1)
        {
            flag 
= 0;
            
for(v=cur[u]; v<=t; v++)
                
if( mat[u][v] > 0 && lev[u] + 1 == lev[v] )
                {
                    flag 
= 1;
                    
break;
                }
            
if( flag )
            {
                cur[u] 
= v + 1;
                pre[v] 
= u;
                a[v] 
= mat[u][v];
                
if( a[v] > a[u] )
                    a[v] 
= a[u];
                u 
= v;
                
if( u == t )
                {
                    ag 
= a[t];
                    flow 
+= ag;
                    
for(v=t; v!=s; v=pre[v])
                    {
                        cur[pre[v]] 
= v;
                        mat[pre[v]][v] 
-= ag;
                        mat[v][pre[v]] 
+= ag;
                        a[v] 
-= ag;
                        
if( mat[pre[v]][v] == 0 )
                            u 
= pre[v];
                    }
                }
            }
            
else
                
if( u != s )
                {
                    lev[u] 
= 0x7fffffff;
                    u 
= pre[u];
                }
                
else    break;
        }
    }
    
return flow;
}

int main()
{
    
while ( EOF != scanf("%d"&n) )
    {
        memset(mat, 
0sizeof(mat));
        
int i, source, user, nodes;
        scanf(
"%d%d%d"&source, &user, &nodes);
        
int s, e, t;
        
for ( i = 0 ; i < nodes ; i++ )
        {
            scanf(
"%*[^(](%d,%d)%d"&s, &e, &t);
            mat[s][e]
=t;
        }
        
for ( i = 0 ; i < source ; i++ )
        {
            scanf(
"%*[^(](%d)%d"&e, &t);
            mat[n][e]
= t;
        }
        
for ( i = 0 ; i < user ; i++ )
        {
            scanf(
"%*[^(](%d)%d"&s, &t);
            mat[s][n
+1]= t;
        }
        printf(
"%d\n", Dinic(n, n+1));
    }
    
return 0;
}
看来用40行的代码,换来时间从近600MS到60MS+,近10倍时间的飞跃,还是挺值得的~

posted on 2011-09-26 09:57 purplest 阅读(161) 评论(0)  编辑 收藏 引用 所属分类: 网络流


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2011年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

导航

统计

常用链接

留言簿

随笔分类(70)

随笔档案(68)

ACMer

搜索

最新随笔

最新评论