hdu1532 Drainage Ditches(最大流模板)

EK 算法 复杂度 n*m*m  https://blog.csdn.net/x_y_q_/article/details/51999466

Dinic算法 复杂度 m*n*n https://www.cnblogs.com/SYCstudio/p/7260613.html

本来这道题 Dinic 和 EK 复杂度应该一样,不知道为什么 EK 0ms   Dinic15ms

EK:

#include<stdio.h>
#include<memory.h>
#include<queue>
using namespace std;
const int sz = 200+10;
const int inf = 10000000+10;
int c[sz][sz];
int flow[sz];
int pre[sz];
int n,m; //有n条边 m个节点 
int bfs(int sc,int dest)
{
    queue<int>q;
    for(int i=1;i<=m;i++)
    {
        pre[i]=-1;
        flow[i]=0;
    }
    pre[sc]=sc;
    flow[sc]=inf;
    q.push(sc);
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
        for(int i=1;i<=m;i++)
        {
            if(pre[i]==-1 && c[now][i]>0)
            {
                pre[i] = now;
                flow[i] = min(flow[now],c[now][i]);
                if(i==dest)
                {
                    break;
                }
                q.push(i);
            }        
        }
    }
    if(pre[dest]==-1)
    {
        return -1;
    }else{
        return flow[dest];
    }
}
int max_flow(int sc,int dest)
{
    int increament ;
    int rs = 0;
    while((increament = bfs(sc,dest))!=-1)
    {
        rs = rs + increament;
        int k = dest;
        while(k!=sc)
        {
            int pp = pre[k];    
            c[pp][k] -= increament;
            c[k][pp] += increament;
            k = pre[k];
        }
    }
    return rs;
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        memset(c,0,sizeof(c));
//        memset(flow,0,sizeof(flow));
//        memset(pre,0,sizeof(pre));
        for(int i=1;i<=n;i++)
        {
            int a,b,ci;
            scanf("%d %d %d",&a,&b,&ci);
            c[a][b] += ci;
        }
        printf("%d\n",max_flow(1,m));
    }
    return 0;
} 


Dinic:

//dinic
#include<stdio.h>
#include<queue>
#include<memory.h>
#include<algorithm>
using namespace std;
const int maxn = 200+10;//顶点数 
const int maxm = (200+10)*3;//边数 
int Head[maxn];//每一个点的最后一条边的位置
int V[maxm];//每一条边指向的点 
int W[maxm];//每一条边的权重 初始化为0 
int Next[maxm];//每一条边的上一条边  初始化为-1 
int depth[maxn];//记录每一个节点的层次  bfs每次初始化为0 
const int inf = 1e9+7;
int cnt;//边数 
//建立层次图 
int bfs(int s,int t)
{
    queue<int>q;
    memset(depth,0,sizeof(depth));
    depth[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(int i = Head[u] ; i!=-1 ; i=Next[i])
        {
            if(W[i]>0 && depth[V[i]]==0)
            {
                depth[V[i]]=depth[u]+1;
                q.push(V[i]);
            }
        }
    }
    if(depth[t]==0)
    {
        return 0;
    }
    return 1;
}
//深搜查找增广路
int dfs(int s,int t,int flow)
{
    if(s==t)
    {
        return flow;        
    }
    for(int i=Head[s] ; i!=-1 ;i=Next[i])
    {
        if(W[i]>0 && depth[s]+1 == depth[V[i]])
        {
            int di = dfs(V[i],t,min(flow,W[i]));
            if(di>0)
            {
                W[i]-=di;
                W[i^1]+=di;
                return di;
            }
        }
    }
    return 0;
} 
//dinic算法
int dinic(int s,int t)
{
    int max_flow = 0;
    while(bfs(s,t))
    {
        int d = 0;
        while(d = dfs(s,t,inf))
        {
            max_flow += d;
        }
    }    
    return max_flow;
} 
void addEdge(int from,int to,int c)
{
    Next[cnt] = Head[from];
    Head[from]=cnt;

    V[cnt]=to;
    W[cnt]=c;
    cnt++;
}
int main()
{
    int n,m;
    while(~scanf("%d %d",&n,&m))
    {
        cnt = 0;
        memset(Head,-1,sizeof(Head));
    //    memset(Next,-1,sizeof(Next));///
        for(int i=1;i<=n;i++)
        {
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            addEdge(a,b,c);
            addEdge(b,a,0);
        }
        printf("%d\n",dinic(1,m));    
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/zark721/article/details/80022176
今日推荐