最大流模板 poj1273

直接求最大流即可

#include <iostream >
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std  ;

struct edge{
    int u,v,w,next ;
}e[250<<1];
int mp[250][250] ,dep[250],vis[250];
const int INF = 0x3f3f3f3f;
int n,m;
int cnt ;
int head[250] ;
void add(int u,int v,int w)
{
    e[cnt].w=w;
    e[cnt].u=u ;
    e[cnt].v=v ;
    e[cnt].next = head[u] ;
    head[u] = cnt++ ;
    e[cnt].w=0;
    e[cnt].u=v ;
    e[cnt].v =u ;
    e[cnt].next=head[v] ;
    head[v] = cnt++ ;
}
int BFS(){
    memset(vis,0,sizeof vis) ;
    memset(dep,-1,sizeof(dep));
    int src=1,des =m;
    queue <int > que ;
    que.push(src) ;
    dep[src] = 0 ;
    vis[src] = 1 ;
    while(!que.empty()){
        int d=que.front() ;
        que.pop() ;
        for(int i = head[d] ;i!=-1 ; i=e[i].next){
            int v  = e[i].v ;
            if(!vis[v] && e[i].w !=0){
                dep[v] = dep[d] +1 ;
                vis[v] = 1;
                que.push(v) ;
            }
        }
    }
    if(dep[des] == -1)
    return 0;

    return 1;
}


int Dinic(){
    int src = 1,des = m;
    long long  ans=0;
    int stack[25000],cur[25000]; ///stack[i为栈,存储当前增广路,  cur[i]存储当前点的后继 跟head是一样的
    while(BFS()){
        //cout<<1;
        memcpy(cur,head,sizeof(head));
        int u=src, top=0;   ///u为当前结点
        while(1){
            if(u==des){    ///增广路已全部进栈
                long long minx=INF ;
                int  loc;
                for(int i=0;i<top;i++)  ///找最小的增广跟并loc记录其在stack中位置
                    if(minx>e[stack[i]].w){    ///以便退回该边继续DFS
                        minx=e[stack[i]].w;
                        loc=i;
                    }
                for(int i=0;i<top;i++){     ///将增广路中的所有边修改
                    e[stack[i]].w-=minx;
                    e[stack[i]^1].w+=minx;
                }
                //cout<<minx<<endl ;
                ans+=minx;
                top=loc;
                u=e[stack[top]].u;   ///当前结点修改为最小边的起点
            }
            for(int i=cur[u];i!=-1;cur[u]=i=e[i].next)  ///找到当前结点对应的下一条边
                if(e[i].w>0 && dep[e[i].v]==dep[u]+1)   ///不满足条件时,修改cur值
                    break;  ///(去掉不合适的占)eg:1-->2 1-->3 1-->4 有边 但只有1-->4 这条边满足条件 就把1到2、3的边给去掉
            if(cur[u]!=-1){   ///当前结点的下一条边存在
                stack[top++]=cur[u];   ///把该边放入栈中
                u=e[cur[u]].v;      ///再从下个点开始找
            }else{
                if(top==0)  ///当前结点无未遍历的下一条边且栈空,DFS找不到下一条增广路
                    break;
                dep[u]=-1;  ///当前结点不在增广路中,剔除该点
                u=e[stack[--top]].u;     ///退栈 回朔,继续查找
            }
        }
    }
    //cout<<ans <<endl;
    return ans;
}

int main()
{
    while(~scanf("%d%d",&n,&m)){
        cnt =0 ;
        memset(head,-1,sizeof head) ;
        memset(mp,0,sizeof mp) ;
        for(int i=0;i<n;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w) ;
            u+=1,v+=1;
            if(!mp[u][v] || mp[u][v] < w ){
                add(u,v,w) ;
                mp[u][v]  = w;
            }
        }
        long long ans = Dinic() ;
        cout<<ans<<endl;

    }
    return 0;
}

 

posted @ 2015-08-11 14:18  Scale_the_heights  阅读(119)  评论(0)    收藏  举报