poj Budget

Budget

建图好题,不知道为什么提交一直TLE。然后,该了几次,看了别人的普通网络流都过了。我认为可能是卡DINIC的某些部分吧。这题就是一道普通的上下界最小流。

建图麻烦,所以说一下建图吧。

建图可以象方格取数的方法一样,把行列拆了,然后最后让行总和或列总和等于题目的要求。这样在满足一下题目的上下界要求后图就建好了。跑两边最大流就Ok了。

因为,一直TLE所以不给出完整代码,只给出建图过程。囧。。。

int main()
{
    int T;
    scanf("%d\n",&T);
    while(T--){
        char ope[5];
        int x,y,c;

        scanf("%d%d\n",&N,&M);

        init();
        memset(in,0,sizeof(in));

        for(int i = 1;i <= N;++i){
            for(int j = 1;j <= M;++j){
                B[i][j] = 0;
                C[i][j] = INF;
            }
        }

        for(int i = 1;i <= N;++i){   //行
            scanf("%d",&c);

            addEdge(ss,i,0);
            in[ss] -= c;
            in[i] += c;
        }

        for(int j = 1;j <= M;++j){  //列
            scanf("%d",&c);

            addEdge(j+N,tt,0);
            in[j + N] -= c;
            in[tt] += c;
        }

        int cas;
        scanf("%d",&cas);
        while(cas--){
            scanf("%d%d%s%d",&x,&y,ope,&c);
            if(c < 0){
                flag = true;
            }
            int x1,x2,y1,y2;
            x1 = x2 = x;
            y1 = y2 = y;
            if(!x) x1 = 1,x2 = N;
            if(!y) y1 = 1,y2 = M;
            for(int i = x1;i <= x2;++i){
                for(int j = y1;j <= y2;++j){
                    if(ope[0] == '=')
                        B[i][j] = C[i][j] = c;
                    else if(ope[0] == '>')
                        B[i][j] = max(B[i][j],c + 1);
                    else
                        C[i][j] = min(C[i][j],c - 1);
                    if(C[i][j] < B[i][j])
                        flag = false;
                }
            }
        }

        if(flag){
            puts("IMPOSSIBLE");
            if(T)puts("");
            continue;
        }

         //建图
        for(int i = 1;i <= N;++i){
            for(int j = 1;j <= M;++j){
                addEdge(i,j + N,C[i][j] - B[i][j]);
                in[i] -= B[i][j];
                in[j+N] += B[i][j];
            }
        }

        int sum = 0;
        for(int i = 1;i <= tt;++i){
            if(in[i] > 0){
               sum += in[i];
               addEdge(src,i,in[i]);
            }
            if(in[i] < 0){
               addEdge(i,sink,-in[i]);
            }
        }

        addEdge(tt,ss,INF);      ///!!!!!!!!!! tt --> ss 不要在粗心了!!!   T_T
        int flow = maxFlow(src,sink);

        if(flow != sum){
            puts("IMPOSSIBLE");
        } else {
           maxFlow(src,sink);
        }
        if(T)puts("");
    }
    return 0;
}
时间: 2024-08-12 06:03:39

poj Budget的相关文章

POJ 2396 Budget 有上下界的网络流

POJ 2396  Budget 题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测.矩阵规模小于200*20. 网络流的模型是显而易见的,不过对于这道题,我们要添加两次源和汇. 第一次添加s连接每一行,t连接每一列,容量上下线都是这行或这列的和. 第二次对每条有容量限制的边(u,v)添加 (ss,v)和( u,tt)容量均为( u,v)的下限. 第三次添加(t,s)容量无穷. 对(ss,tt)求最大流,若ss出发和进入tt的边均满流则有解,

POJ 2396 Budget (有源汇有上下界的可行流)

POJ 2396 Budget 链接:http://poj.org/problem?id=2396 题意:给定一个M*N的矩阵,给定每行每列的和,以及其中一些值的限定条件,问能否构成一个可行的矩阵. 思路: 添加一个源点,向每行连边,每条边的上下界都为该行的和:添加一个汇点,每列向汇点连边,边的上下界都为该列的和.然后每行向每列连边,边的上下界一开始为(0,INF),之后通过一些限定条件更新. 现在问题成了求一个有源汇有上下界的可行流.只需要再添加一个超级源点,一个超级汇点,并且将原图的汇点向源

poj 2396 Budget 边容量有上下界的最大流

题意: 给一个矩阵的每行和及每列和,在给一些行列或点的限制条件.求一个满足的矩阵. 分析: 转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法. 代码: //poj 2396 //sep9 #include <iostream> #include <queue> #include <algorithm> using namespace std; const int maxN=210; const int maxM=40; const int max

【POJ 2396】 Budget

Budget Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 6317 Accepted: 2393 Special Judge Description We are supposed to make a budget proposal for this multi-site competition. The budget proposal is a matrix where the rows represent differ

POJ 2396 Budget【网络流】

题意: cas           //测试数据组数 n m         //行数 列数 a1 a2 ... an    //每行的和 b1 b2 ... bn   //每列的和 q            //操作数量 //接下来q行 a b >/</= c     //若a为0则表示一整列,b为0表示一整行,否则a代表第几行,b代表第几列,操作表示选中区域或者某个元素要严格大于或者严格小于或者等于c 求:判断是否存在合法矩阵,如果存在输出任一合法矩阵(每个元素都要求非负),否则输出“IM

poj 2396 Budget【有上下界的网络流】

第一步:建立无源汇有上下界的网络模型 每行 i 作为一个点并连边(s, i, Ri, Ri),每列 j 作为一个点并连边(j, t, Cj, Cj),设 Uij, Lij 分别表示第 i 行第 j 列元素的上下界,初始时设 Uij=∞, Lij=0.按照给定的约束条 件不断调整 Uij, Lij,若出现 Lij > Uij 的情况则已经不存在合法解.对所有元素加 边(i, j, Lij, Uij).另添加边(t, s, 0, ∞)消去原网络的源汇. 第二步:转化为最大流模型 新建源 s'和汇 t

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

poj 1384 Piggy-Bank(完全背包)

http://poj.org/problem?id=1384 Piggy-Bank Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7900 Accepted: 3813 Description Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income f

poj2396 Budget 有源汇上下界可行流

/** 题目:poj2396 Budget 链接:http://poj.org/problem?id=2396 题意: 给定一个n*m矩阵,矩阵元素未知.已知第1~n行的元素和,第1~m列的元素和.以及元素的一些数据范围. 求一个可行的矩阵. 思路: 联想到以前没有下届的做法,用一个s连接所有的行节点,容量为该行的和,所有的列节点连接t,容量为该列的和. 所有的行节点连接所有的列节点,容量为无穷,然后求s到t的最大流.如果从s出发的弧都是满载的,那么有解. 所有行到所有列的flow为对应的行列位