POJ 2396 Budget(有上下界的网络流)

代码算是一个模版吧,主要难点是能够看出是个网络流以及如何建图,这还需要做题来积累经验。
//
//  main.cpp
//  Richard
//
//  Created by 邵金杰 on 16/8/15.
//  Copyright © 2016年 邵金杰. All rights reserved.
//


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=250+5;
const int INF=100000000;
int cap[maxn][maxn],flow[maxn][maxn],low[maxn][maxn],high[maxn][maxn];
int r[maxn],c[maxn],in[maxn],out[maxn],Layer[maxn],vis[maxn];
int n,m;
void intial()
{
    memset(cap,0,sizeof(cap));
    memset(flow,0,sizeof(flow));
    memset(low,0,sizeof(low));
    memset(high,0,sizeof(high));
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
}
void Input()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&r[i]);
    for(int i=1;i<=m;i++)
        scanf("%d",&c[i]);
}
void creat_graph()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            high[i][j+n]=INF;
        }
    }
    int u,v,w;
    char ch;
    int times;
    scanf("%d",×);
    while(times--)
    {
        scanf("%d %d %c %d",&u,&v,&ch,&w);
        if(u==0&&v!=0)
        {
            if(ch=='=')
            {
                for(int i=1;i<=n;i++)
                    low[i][v+n]=high[i][v+n]=w;
            }
            else if(ch=='>')
            {
                for(int i=1;i<=n;i++)
                    low[i][v+n]=max(low[i][v+n],w+1);
            }
            else if(ch=='<')
            {
                for(int i=1;i<=n;i++)
                    high[i][v+n]=min(high[i][v+n],w-1);
            }
        }
        else if(u!=0&&v==0)
        {
            if(ch=='=')
            {
                for(int i=1;i<=m;i++)
                    low[u][i+n]=high[u][i+n]=w;
            }
            else if(ch=='>')
            {
                for(int i=1;i<=m;i++)
                    low[u][i+n]=max(low[u][i+n],w+1);
            }
            else if(ch=='<')
            {
                for(int i=1;i<=m;i++)
                    high[u][i+n]=min(high[u][i+n],w-1);
            }
        }
        else if(u==0&&v==0)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(ch=='=') low[i][j+n]=high[i][j+n]=w;
                    else if(ch=='>') low[i][j+n]=max(low[i][j+n],w+1);
                    else if(ch=='<') high[i][j+n]=min(high[i][j+n],w-1);
                }
            }
        }
        else if(u!=0&&v!=0)
        {
            if(ch=='=') low[u][v+n]=high[u][v+n]=w;
            else if(ch=='>') low[u][v+n]=max(low[u][v+n],w+1);
            else if(ch=='<') high[u][v+n]=min(high[u][v+n],w-1);
        }
    }
    int s=0,e=n+m+1;
    for(int i=1;i<=n;i++)
        low[s][i]=high[s][i]=r[i];
    for(int j=1;j<=m;j++)
        low[j+n][e]=high[j+n][e]=c[j];
}
bool bfs(int s,int e,int num)
{
    memset(Layer,-1,sizeof(Layer));
    queue<int> q;
    q.push(s);
    Layer[s]=0;
    while(!q.empty())
    {
        int v=q.front();
        q.pop();
        for(int i=0;i<num;i++)
        {
            if(cap[v][i]&&Layer[i]==-1)
            {
                Layer[i]=Layer[v]+1;
                q.push(i);
            }
        }
    }
    if(Layer[e]!=-1) return true;
    return false;
}
int dfs(int s,int e,int num)
{
    memset(vis,0,sizeof(vis));
    int maxflow=0;
    vector<int> v;
    v.push_back(s);
    vis[s]=1;
    while(v.size())
    {
        int nd=v[v.size()-1];
        if(nd==e)
        {
            int minflow=INF,position=0;
            for(int i=1;i<v.size();i++)
            {
                int p1=v[i-1];
                int p2=v[i];
                if(minflow>cap[p1][p2])
                {
                    minflow=cap[p1][p2];
                    position=p1;
                }
            }
            maxflow+=minflow;
            for(int i=1;i<v.size();i++)
            {
                int p1=v[i-1];
                int p2=v[i];
                cap[p1][p2]-=minflow;
                cap[p2][p1]+=minflow;
                flow[p1][p2]+=minflow;
                flow[p2][p1]-=minflow;
            }
            while(v.size()&&v[v.size()-1]!=position)
            {
                vis[v[v.size()-1]]=0;
                v.pop_back();
            }
        }
        else
        {
            int i;
            for(i=0;i<num;i++)
            {
                if(cap[nd][i]&&!vis[i]&&Layer[i]==Layer[nd]+1)
                {
                    vis[i]=1;
                    v.push_back(i);
                    break;
                }
            }
            if(i>=num) v.pop_back();
        }
    }
    return maxflow;
}
int Dinic(int s,int e,int num)
{
    int ans=0;
    while(bfs(s,e,num)){
        ans+=dfs(s,e,num);
    }
    return ans;
}
void solve(int s,int e,int num)
{
    int ss,ee,sum=0;
    ss=num,ee=num+1;
    for(int i=0;i<num;i++)
    {
        for(int j=0;j<num;j++)
        {
            cap[i][j]+=high[i][j]-low[i][j];
            out[i]+=low[i][j];
            in[j]+=low[i][j];
            sum+=low[i][j];
        }
    }
    for(int i=0;i<num;i++)
    {
        cap[ss][i]=in[i];
        cap[i][ee]=out[i];
    }
    cap[e][s]=INF;
    int res=Dinic(ss,ee,num+2);
    if(res!=sum)
    {
        printf("IMPOSSIBLE\n");//坑点啊,一摸一样网页上复制下来的,最后还有个空格,但是交了没AC,最后删了空格AC了
        return ;
    }
    cap[s][e]=cap[e][s]=0;
    Dinic(s,e,num);
    for(int i=1;i<=n;i++)
    {
        printf("%d",flow[i][1+n]+low[i][1+n]);
        for(int j=2;j<=m;j++)
        {
            printf(" %d",flow[i][j+n]+low[i][j+n]);
        }
        printf("\n");
    }
}
int main()
{
    int t,s,e;
    scanf("%d",&t);
    while(t--)
    {
        intial();
        Input();
        creat_graph();
        s=0,e=n+m+1;
        solve(s,e,e+1);
        printf("\n");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值