随笔-68  评论-10  文章-0  trackbacks-0
/*
     dinic算法,边表存储(仿指针),实用于稀疏图,O(mn^2)
*/


#include
<iostream>
using namespace std;

const int maxn=205;  //最大定点数
const int maxm=205;  //最大边数
const int inf=0x7fffffff;

struct Edge
{
    
int ver;   //下一顶点
    int flow;  //
    int next;  //下一条边
    int op;    //反向边
}
edge[2*maxm];

int head[maxn];  //i顶点引出的首条边序号为head[i];
int level[maxn];  //
int m,n,src,sin;   //边数,顶点数,源点,汇点
int tot;  //边序号

int min(int a,int b)
{
    
return a<b? a:b;
}


void add_edge(int u,int v,int w)
{
    edge[tot].ver
=v;
    edge[tot].flow
=w;
    edge[tot].next
=head[u];
    head[u]
=tot++;
    edge[tot].ver
=u;
    edge[tot].flow
=0;
    edge[tot].next
=head[v];
    head[v]
=tot++;

    edge[head[u]].op
=head[v];
    edge[head[v]].op
=head[u];
}


void bfs_level()
{
    memset(level,
-1,sizeof(level));
    
int q[maxn],front=0,rear=0;
    level[src]
=0;
    q[rear
++]=src;
    
while(front<rear)
    
{
        
int k=q[front++]; 
        
for(int i=head[k];i!=-1;i=edge[i].next)
        
{
            
if(level[edge[i].ver]==-1&&edge[i].flow>0)
            
{
                level[edge[i].ver]
=level[k]+1;
                q[rear
++]=edge[i].ver;
            }

        }

    }

}


int dfs_maxflow()
{
    
int flow=0;
    
int stk[maxn],top=0,mint;  //栈,栈顶指针,可改进流量
    bool vis[maxn]; 
    
int prt[maxn];   //记录可增广路径
    int curedge[maxn];  //记录每个顶点引出的当前边序号
    int i,j,curptr;
    memset(vis,
false,sizeof(vis));
    
for(i=1;i<=n;i++) curedge[i]=head[i];
    stk[top]
=src;
    
while(top>=0)
    
{
        
if(stk[top]==sin)
        
{
            mint
=inf;
            
for(j=top;j>=1;j--)
                mint
=min(mint,edge[prt[stk[j]]].flow);
            
for(j=top;j>=1;j--)
            
{
                edge[prt[stk[j]]].flow
-=mint;
                edge[edge[prt[stk[j]]].op].flow
+=mint;
                
if(edge[prt[stk[j]]].flow==0) curptr=j;
            }

            top
=curptr-1;
            flow
+=mint;
        }

        
else
        
{
            
for(i=curedge[stk[top]];i!=-1;i=edge[i].next)
            
{
                
if(!vis[edge[i].ver]&&level[edge[i].ver]==level[stk[top]]+1&&edge[i].flow>0)
                
{
                    curedge[stk[top]]
=edge[i].next;
                    stk[
++top]=edge[i].ver;
                    prt[stk[top]]
=i;
                    
break;
                }

            }

            
if(i==-1)
            
{
                vis[stk[top]]
=true;
                top
--;
            }

        }

    }

    
return flow;
}


int dinic()
{
    
int maxflow=0, t;
    
while(1)
    
{
        bfs_level();
        
if(level[sin]==-1return maxflow;
        t
=dfs_maxflow();
        
if(!t) break;
        maxflow
+=t;
    }

    
return maxflow;
}


int main()
{
     
while(scanf("%d%d",&m,&n)!=EOF)
     
{
         
int u,v,w;

         src
=1;
         sin
=n;
         tot
=0;
         memset(head,
-1,sizeof(head));

         
for(int i=0;i<m;i++)
         
{
             scanf(
"%d%d%d",&u,&v,&w);
             add_edge(u,v,w);
         }

         
         printf(
"%d\n",dinic());
     }

     
return 0;
}

posted on 2011-05-10 13:07 wuxu 阅读(271) 评论(0)  编辑 收藏 引用 所属分类: 图论

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