poj-1273 Drainage Ditches 最大流

来源:互联网 发布:王者荣耀mvp新算法 编辑:程序博客网 时间:2024/05/17 15:20

http://poj.org/problem?id=1273

//EK算法#include "stdio.h"#include "queue"using namespace std;const int maxn = 205;int map[maxn][maxn],path[maxn];           //邻接数组 前驱数组int n,m;bool EK_Bfs( int start,int end )        //广搜增广路{int i,j;queue<int>que;                      //广搜队列bool vis[maxn]={false};for( i=1;i<=m;i++ )path[i] = -1;que.push( start );vis[start] = true;while( !que.empty() ){int e = que.front();if( e==end )                //当队头弹出的点为终点时 即可判断广路找到return true;que.pop();for( i=1; i<=m; i++ ){if( map[e][i] && !vis[i] )   //当边容量为非空 且增广点未标记{vis[i] = true;path[i] = e;         //记录前驱que.push(i);         //入队}}}return false;}int EK_Max_Flow( int st,int end )  //起点 终点{int k,min,ans=0;while( EK_Bfs( st,end ) )       //当增广成功{min = 1<<30;k = end;while( path[k] != -1 )             //寻找瓶颈{min = min < map[path[k]][k] ? min : map[path[k]][k];k = path[k];}ans += min;                  //累加最大流k = end;while( path[k] != -1 )             //修改路径上的边容量{map[path[k]][k] -= min;map[k][path[k]] += min;k = path[k];}}return ans;}int main(){int i,j,a,b,c;while( scanf("%d%d",&n,&m)==2 ){for( i=1;i<=m;i++ )for( j=1;j<=m;j++ )map[i][j] = 0;for( i=1;i<=n;i++ ){scanf("%d%d%d",&a,&b,&c);       //可能出现重边 要用+=map[a][b] += c;}int ans = EK_Max_Flow(1, m);printf("%d\n",ans);}return 0;}


//Dinic#include "stdio.h"#include "queue"#include "string.h"#include "vector"#include "algorithm"using namespace std;const int maxn = 205;const int inf = 1<<30;int n,m;int cap[maxn][maxn];int dis[maxn],vis[maxn];bool Dinic_Bfs( int st,int end )//BFS分层{memset( vis,0,sizeof(vis) );memset( dis,0,sizeof(dis) );queue<int>que;dis[st] = 0; vis[st] = true;que.push(st);while( !que.empty() ){int u = que.front();  que.pop();if( u == end )//分层到汇点就结束return true;for( int v = 1; v <= n; v ++ ){if( !vis[v] && cap[u][v] ){vis[v] = true;dis[v] = dis[u] + 1;que.push( v );}}}return false;}int Dinic_Dfs( int st,int maxf,int end )//沿BFS的分层增广{int ans = 0,flow;if( st == end )return maxf;for( int i = 1; i <= n; i ++ ){if( cap[st][i] && dis[i] == dis[st] + 1 ){flow = Dinic_Dfs( i,cap[st][i]<maxf?cap[st][i]:maxf,end);//i点能流走的流量cap[st][i] -= flow;//增广cap[i][st] += flow;ans += flow;maxf -= flow;if( !maxf )return ans;}}if( !ans )//注意没得流的时候要标记为-1dis[st] = -1;return ans;}int Dinic( int st,int end ){int ans = 0;while( Dinic_Bfs(st,end) ){//分层ans += Dinic_Dfs( st,inf,end );  //增广}return ans;}int main(){//freopen("data.txt","r",stdin);int a,b,c;    while( scanf("%d%d",&m,&n) != EOF ){memset( cap,0,sizeof(cap) );for( int i = 1; i <= m; i ++ ){scanf("%d%d%d",&a,&b,&c);cap[a][b] += c;}printf("%d\n",Dinic(1,n));}     return 0;}

#include "stdio.h"#include "queue"using namespace std;const int maxn = 205;const int inf = 1<<30;int dis[maxn];bool vis[maxn];int n,m,pos;struct Node{    int id,w,pos;    Node *next;}node[maxn*10];struct Head{    Node *first;}head[maxn];void add(int a,int b,int c){    node[pos].id = b; node[pos].w = c; node[pos].pos = pos;    node[pos].next = head[a].first;    head[a].first = &node[pos];    pos++;    node[pos].id = a; node[pos].w = 0; node[pos].pos = pos;    node[pos].next = head[b].first;    head[b].first = &node[pos];    pos++;}bool dinic_bfs( int start,int end ){    Node *p;    memset(vis,0,sizeof(vis));    memset(dis,0,sizeof(dis));        vis[start] = true;    dis[start] = 0;    queue<int>q;    q.push(start);    while( !q.empty() )    {        int e = q.front();        q.pop();        if( e==end )            return true;        for( p = head[e].first; p!=NULL; p=p->next )        {            if( !vis[p->id] && p->w )            {                vis[p->id] = true;                q.push( p->id );                dis[p->id] = dis[e] + 1;            }        }    }    return false;}int dinic_dfs( int start,int maxf,int end ){    if( start==end )        return maxf;    int ans = 0,flow;    for( Node *p=head[start].first; p!=NULL; p=p->next )    {        if( dis[p->id] == dis[start] + 1 )        {            flow = dinic_dfs( p->id,p->w < maxf?p->w:maxf,end );            ans += flow;            maxf -= flow;            p->w -= flow;            node[p->pos^1].w +=flow;            if( maxf==0 )                break;        }    }    return ans;}int Dinic( int start,int end ){    int ans = 0;    while( dinic_bfs( start,end ) )        ans += dinic_dfs( start, inf ,end );    return ans;}int main(){    int i,j,a,b,c;    while( scanf("%d%d",&n,&m)==2 )    {        pos = 0;        for( i=1; i<=m; i++ )        {            head[i].first = NULL;        }        for( i=1; i<=n; i++ )        {            scanf("%d%d%d",&a,&b,&c);            add(a,b,c);        }        int ans = Dinic(1,m);        printf("%d\n",ans);    }    return 0;}

//SAP#include "stdio.h"#include "queue"#include "string.h"#include "vector"#include "algorithm"using namespace std;const int maxn = 205;const int inf = 1<<30;int n,m;int cap[maxn][maxn];int pre[maxn],level[maxn],gap[maxn];   //前驱 距离标号 gap常数优化int SAP( int st,int end ){memset( pre,-1,sizeof(pre) );memset( level,0,sizeof(level) );memset( gap,0,sizeof(gap) );gap[0] = n+1;int v,u = pre[st] = st,maxf = 0,aug = inf;while( level[st] < n+1 ){for( v = 1; v <= n; v ++ ){if( cap[u][v] && level[u] == level[v] + 1 )break;}if( v <= n ){pre[v] = u;u = v;if( v == end ){aug = inf;for( int i = v; i != st; i = pre[i] )if( aug > cap[pre[i]][i] )aug = cap[pre[i]][i];maxf += aug;for( int i = v; i != st; i = pre[i] ){cap[pre[i]][i] -= aug;cap[i][pre[i]] += aug;}u = st;}}else{int minlevel = n;for( v = 1; v <= n; v ++ )if( cap[u][v] > 0 && minlevel > level[v] )minlevel = level[v];gap[level[u]] --;if( !gap[level[u]] )break;level[u] = minlevel + 1;gap[level[u]] ++;u = pre[u];}}return maxf;}int main(){//freopen("data.txt","r",stdin);int a,b,c;    while( scanf("%d%d",&m,&n) != EOF ){memset( cap,0,sizeof(cap) );for( int i = 1; i <= m; i ++ ){scanf("%d%d%d",&a,&b,&c);cap[a][b] += c;}printf("%d\n",SAP(1,n));}     return 0;}


#include "stdio.h"#include "queue"#include "algorithm"using namespace std;const int maxn = 210;const int inf = 1<<30;int n,m,pos;struct Node{int v,w,next;Node() {};Node( int v,int w,int next ):v(v),w(w),next(next) {}}node[100*maxn];int head[maxn];void add( int u,int v,int w ){node[pos] = Node(v,w,head[u]);head[u] = pos ++;node[pos] = Node(u,0,head[v]);head[v] = pos ++;}int ISAP( int st,int end ){int curedge[maxn],pre[maxn],h[maxn],gap[maxn];int u,neck,tmp,i;memset( h,0,sizeof(h) );memset( gap,0,sizeof(gap) );int cur_flow,flow_ans = 0;for( int i = 1; i <= n; i ++ )curedge[i] = head[i];gap[0] = n;u = st;while( h[st] < n ){if( u == end ){cur_flow = inf;for( i = st; i != end; i = node[curedge[i]].v ){if( cur_flow > node[curedge[i]].w ){neck = i;cur_flow = node[curedge[i]].w;}}for( i = st; i != end; i = node[curedge[i]].v ){tmp = curedge[i];node[tmp].w -= cur_flow;node[tmp^1].w += cur_flow;}flow_ans += cur_flow;u = neck;}for( i = curedge[u]; i != -1; i = node[i].next ){if( node[i].w && h[u] == h[node[i].v] + 1 )break;}if( i != -1 ){curedge[u] = i;pre[node[i].v] = u;u = node[i].v;}else{if( 0 == --gap[h[u]] )break;curedge[u] = head[u];for( tmp = n,i = head[u]; i != -1; i = node[i].next )if( node[i].w )tmp = tmp < h[node[i].v]?tmp:h[node[i].v];h[u] = tmp + 1;gap[h[u]] ++;if( u != st )u = pre[u];}}return flow_ans;}int main(){//freopen("data.txt","r",stdin);char ch;int u,v,w;    while( scanf("%d%d",&m,&n) == 2 ){memset(head,-1,sizeof(head));for( int i = 1; i <= m; i ++ ){scanf("%d%d%d",&u,&v,&w);add(u,v,w);}printf("%d\n",ISAP(1,n));}    return 0;}



原创粉丝点击