hdu1532Drainage Ditches 最大流模板水题

感觉这道题纯粹就是试模板的,给一个有向图,求其最大流
Dinic算法:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define inf 300
#define lim 0x7fffffff
int flow[inf][inf];
int dis[inf];
int n,m;
int bfs()
{
    int i;
    memset(dis,-1,sizeof(dis));
    dis[1]=0;
    queue<int> que;
    que.push(1);
    while(que.size())
    {
       int now=que.front();
       que.pop();
       for(i=1;i<=n;i++)
       {
           if(flow[now][i]>0&&dis[i]<0)
           {
               dis[i]=dis[now]+1;
               que.push(i);
           }
       }
    }
    if(dis[n]>0)
    return 1;
    return 0;
}
int dfs(int x,int mx)
{
    int i;int a;
    if(x==n)
    return mx;
    for(i=1;i<=n;i++)
    {
           if(flow[x][i]>0&&dis[i]==dis[x]+1&&(a=dfs(i,min(mx,flow[x][i]))))
           {
               flow[x][i]-=a;
               flow[i][x]+=a;
               return a;
           }
    }
    return 0;
}
int main()
{
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        int si,ei,ci;
        memset(flow,0,sizeof(flow));
        while(m--)
        {
            scanf("%d%d%d",&si,&ei,&ci);
            flow[si][ei]+=ci;
        }
        int ans=0;
        int res;
        while(bfs())
        {
            while(res=dfs(1,lim))
            ans+=res;
        }
        printf("%d\n",ans);
    }
    return 0;
}

ISAP算法:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int maxn = 210 ;
const int inf = 0x7fffffff ;
int cur[maxn] , gap[maxn] , pre[maxn] ;
int head[maxn] , dis[maxn] ;
int st , en , nedge , n  , m ;
struct Edge
{
    int v , w ;
    int next ;
}edge[maxn<<1] ;
void addedge(int u , int v , int w)
{
    edge[nedge].v = v ;
    edge[nedge].w = w ;
    edge[nedge].next = head[u] ;
    head[u] = nedge++ ;
    edge[nedge].v = u ;
    edge[nedge].w = 0;
    edge[nedge].next = head[v] ;
    head[v] = nedge++ ;
}
void bfs()
{
    memset(dis, -1 , sizeof(dis)) ;
    memset(gap , 0 , sizeof(gap)) ;
    queue<int> que ;
    dis[en] = 0 ; gap[0]++ ;
    que.push(en) ;
    while(que.size())
    {
        int u = que.front() ;que.pop() ;
        for(int i = head[u] ; i != -1 ;i =  edge[i].next)
        {
            int v = edge[i].v ;
            if(dis[v] < 0 && edge[i^1].w > 0)
            {
                dis[v] = dis[u] + 1 ;
                gap[dis[v]]++ ;
                que.push(v) ;
            }
        }
    }
}
int isap()
{
    bfs() ;
    memset(pre , -1 , sizeof(pre)) ;
    memcpy(cur , head, sizeof(head)) ;
    int u = pre[st] = st ;
    gap[0] = n ;
    int  maxflow =0 ;
    int aug = inf ;bool flag  ;
    while(dis[st] < n)
    {
        flag = false ;
        for(int i = cur[u] ;i != -1 ;i = edge[i].next)
        {
            int v = edge[i].v ;
            if(dis[u] == dis[v] + 1 && edge[i].w > 0)
            {
                flag = true ;
                cur[u] = i ;
                pre[v] = u ; u = v ;
                aug = min(aug , edge[i].w) ;
                if(v == en)
                {
                    maxflow += aug ;
                    for(u = pre[v] ; ; u = pre[u])
                    {
                        edge[cur[u]].w -= aug ;
                        edge[cur[u]^1].w += aug ;
                        if(u == st)break;
                    }
                    aug = inf ;
                }
                break ;
            }
        }
        if(flag)continue ;
        int mi = n;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(dis[v] < mi && edge[i].w > 0)
            {
                mi=dis[v];
                cur[u]=i;
            }
        }
        if((--gap[dis[u]]) == 0)break ;
        dis[u] = mi + 1 ;
        gap[dis[u]]++ ;
        u = pre[u] ;
    }
    return maxflow ;
}
int main()
{
    //freopen("in.txt" , "r" , stdin) ;
    while(~scanf("%d%d" , &m  , &n))
    {
        memset(head, -1 , sizeof(head)) ;
        nedge = 0 ;
        int u , v , w ;
        while(m--)
        {
            scanf("%d%d%d" , &u , &v , &w) ;
            addedge(u  ,v , w);
        }
        st = 1 ; en = n ;
        cout<<isap()<<endl;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值