题意:

      要求构造一个矩阵,给你行和,列和,还有一些点的上下范围,输出一个满足题意的矩阵。

思路:

      这个题目很经典,这是自己看上下流后接触的第一道题,感觉很基础的一道题目,现在我们来分析下,如果这个题目是只给行和,列和,让我们构造矩阵应该很简单了,直接一遍最大流,然后判断是否满流,满流就把残余网络拿出来,整理下就是答案了,关键这个题

目就是不但要求满流,某些点还有上限制,或者下限制,那么就直接是上下流呗,对了还有一个地方提醒一下,在建图之前判断一下有没有输入数据冲突的情况,下面说关键部分,也就是建图,建图之前定义几个变量,s(源点),t(汇点),ss(超级源点),tt(超级汇点).


s连接所有的行i              add(s ,i ,行和 , 行和);

所有的列j连接终点t          add(j ,t ,列和 ,列和);

建立一条t -> s              add(t ,s ,0 ,INF);//为了把有源汇的最大流变成无源的

对于任意两点i,j             add(i ,j ,下限 ,上限);

简单说下上下界网络流可行流判断

首先,可行流的判断就是根据在流里面,任意点的流入和流出永远都必须是相等的。

对于一个加边操作,a -> b ,下界 上界 可以这样处理

a -> b 流量为上界减去下界   这个可以叫自由边(就是不是必须流的边)

a -> tt ,ss -> b 流量都是下界   这两个叫做必须边,要想有解,必须边最后必须满流 

如果是有源的,那么我们就 add(t ,s ,0 ,INF);变成无源

最后跑一遍 ss,tt的最大流,如果满流则有可行解,输出答案的话知道把所有自由边拿出来,加上下限就可以了。(因为此时下限已满流).


#include<stdio.h>
#include<string.h>
#include<queue> #define N_node 240
#define N_edge 50000
#define INF 1000000000 using namespace std; typedef struct
{
int from ,to ,next ,cost;
}STAR; typedef struct
{
int x ,t;
}DEP; STAR E[N_edge];
DEP xin ,tou;
int list[N_node] ,listt[N_node] ,tot;
int deep[N_node] ,sum_must;
int map[220][22][3];
int Ans[220][22]; int maxx(int x ,int y)
{
return x > y ? x : y;
} int minn(int x ,int y)
{
return x < y ? x : y;
} void add(int a ,int b ,int c)
{
E[++tot].from = a;
E[tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot; E[++tot].from = b;
E[tot].to = a;
E[tot].cost = 0;
E[tot].next = list[b];
list[b] = tot;
} void ADD(int a ,int b ,int c ,int d ,int ss ,int tt)
{
add(a ,b ,d - c);
add(a ,tt ,c);
add(ss ,b ,c);
sum_must += c;
} bool BFS_Deep(int s ,int t ,int n)
{
xin.x = s ,xin.t = 0;
queue<DEP>q;
q.push(xin);
memset(deep ,255 ,sizeof(deep));
deep[s] = 0;
while(!q.empty())
{
tou = q.front();
q.pop();
for(int k = list[tou.x] ;k ;k = E[k].next)
{
xin.x = E[k].to;
xin.t = tou.t + 1;
if(deep[xin.x] != -1 || !E[k].cost)
continue;
deep[xin.x] = xin.t;
q.push(xin);
}
}
for(int i = 0 ;i <= n ;i ++)
listt[i] = list[i];
return deep[t] != -1;
} int DFS_Flow(int s ,int t ,int flow)
{
if(s == t) return flow;
int nowflow = 0;
for(int k = listt[s] ;k ;k = E[k].next)
{
listt[s] = k;
int to = E[k].to;
int c = E[k].cost;
if(deep[to] != deep[s] + 1 || !c)
continue;
int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));
nowflow += tmp;
E[k].cost -= tmp;
E[k^1].cost += tmp;
if(nowflow == flow) break;
}
if(!nowflow) deep[s] = 0;
return nowflow;
} int DINIC(int s ,int t ,int n)
{
int ans = 0;
while(BFS_Deep(s ,t ,n))
{
ans += DFS_Flow(s ,t ,INF);
}
return ans;
} bool jude(int n ,int m)
{
for(int i = 1 ;i <= n ;i ++)
for(int j = 1 ;j <= m ;j ++)
if(map[i][j][1] > map[i][j][2]) return 0;
return 1;
} int main ()
{
int a ,b ,c ,i ,j ,n ,m ,w ,T;
char str[4];
scanf("%d" ,&T);
while(T--)
{
scanf("%d %d" ,&n ,&m);
memset(list ,0 ,sizeof(list)) ,tot = 1;
sum_must = 0;
int s = 0 ,t = n + m + 1 ,ss = n + m + 2 ,tt = n + m + 3;
for(i = 1 ;i <= n ;i ++)
{
scanf("%d" ,&a);
ADD(s ,i ,a ,a ,ss ,tt);
}
for(i = 1 ;i <= m ;i ++)
{
scanf("%d" ,&a);
ADD(i + n ,t ,a ,a ,ss ,tt);
} for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
map[i][j][1] = 0 ,map[i][j][2] = INF; scanf("%d" ,&w);
while(w--)
{
scanf("%d %d %s %d" ,&a ,&b ,str ,&c);
if(a && b)
{
if(str[0] == '<') map[a][b][2] = minn(map[a][b][2] ,c - 1);
if(str[0] == '=') map[a][b][1] = maxx(map[a][b][1] ,c) ,map[a][b][2] = minn(map[a][b][2] ,c);
if(str[0] == '>') map[a][b][1] = maxx(map[a][b][1] ,c + 1);
}
if(a && !b)
{
for(j = 1 ;j <= m ;j ++)
{
if(str[0] == '<') map[a][j][2] = minn(map[a][j][2] ,c - 1);
if(str[0] == '=') map[a][j][1] = maxx(map[a][j][1] ,c) ,map[a][j][2] = minn(map[a][j][2] ,c);
if(str[0] == '>') map[a][j][1] = maxx(map[a][j][1] ,c + 1);
}
}
if(!a && b)
{
for(j = 1 ;j <= n ;j ++)
{
if(str[0] == '<') map[j][b][2] = minn(map[j][b][2] ,c - 1);
if(str[0] == '=') map[j][b][1] = maxx(map[j][b][1] ,c) ,map[j][b][2] = minn(map[j][b][2] ,c);
if(str[0] == '>') map[j][b][1] = maxx(map[j][b][1] ,c + 1);
}
}
if(!a && !b)
{
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
{
if(str[0] == '<') map[i][j][2] = minn(map[i][j][2] ,c - 1);
if(str[0] == '=') map[i][j][1] = maxx(map[i][j][1] ,c) ,map[i][j][2] = minn(map[i][j][2] ,c);
if(str[0] == '>') map[i][j][1] = maxx(map[i][j][1] ,c + 1);
}
}
}
if(!jude(n ,m))
{
puts("IMPOSSIBLE");
continue;
}
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
ADD(i ,j + n ,map[i][j][1] ,map[i][j][2] ,ss ,tt);
ADD(t ,s ,0 ,INF ,ss ,tt);
int Flow = DINIC(ss ,tt ,tt);
if(Flow != sum_must)
{
puts("IMPOSSIBLE");
continue;
}
for(i = 2 ;i <= tot ;i ++)
if(E[i].from >= 1 && E[i].from <= n && E[i].to >= n + 1 && E[i].to <= n + m)
Ans[E[i].from][E[i].to - n] = E[i^1].cost + map[E[i].from][E[i].to - n][1];
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
if(j == m)printf("%d\n" ,Ans[i][j]);
else printf("%d " ,Ans[i][j]);
if(T) puts("");
}
return 0;
}

POJ 2396 构造矩阵(上下流)的更多相关文章

  1. POJ 2396 Budget 有上下界的网络流

    POJ 2396  Budget 题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测.矩阵规模小于200*20. 网络流的模型是显而易见的,不过对 ...

  2. POJ 2396 Budget ——有上下界的网络流

    给定矩阵的每行每列的和,和一些大于小于等于的限制.然后需要求出一组可行解. 上下界网络流. 大概的思想就是计算出每一个点他需要强行流入或者流出的量,然后建出超级源点和汇点,然后删除下界,就可以判断是否 ...

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

    题意: 给一个矩阵的每行和及每列和,在给一些行列或点的限制条件.求一个满足的矩阵. 分析: 转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法. 代码: //poj 2396 / ...

  4. poj 3735 Training little cats(构造矩阵)

    http://poj.org/problem?id=3735 大致题意: 有n仅仅猫,開始时每仅仅猫有花生0颗,现有一组操作,由以下三个中的k个操作组成: 1. g i 给i仅仅猫一颗花生米 2. e ...

  5. POJ 3233 Matrix Power Series(构造矩阵求等比)

    Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak. ...

  6. POJ 3070 Fibonacci(矩阵高速功率)

    职务地址:POJ 3070 用这个题学会了用矩阵高速幂来高速求斐波那契数. 依据上个公式可知,第1行第2列和第2行第1列的数都是第n个斐波那契数.所以构造矩阵.求高速幂就可以. 代码例如以下: #in ...

  7. hdu 5015 233 Matrix(构造矩阵)

    http://acm.hdu.edu.cn/showproblem.php?pid=5015 由于是个二维的递推式,当时没有想到能够这样构造矩阵.从列上看,当前这一列都是由前一列递推得到.依据这一点来 ...

  8. [数学-构造矩阵]NEFU 1113

    依据题意.我已经推导出tn的公式.ti=ti.a+ti.b,ti.a=5*t(i-1).a+4*t(i-1).b,ti.b=t(i-1).a+t(i-1).b 然而以下居然不能继续推到sn的公式!!! ...

  9. HDU1757-A Simple Math Problem,矩阵快速幂,构造矩阵水过

    A Simple Math Problem 一个矩阵快速幂水题,关键在于如何构造矩阵.做过一些很裸的矩阵快速幂,比如斐波那契的变形,这个题就类似那种构造.比赛的时候手残把矩阵相乘的一个j写成了i,调试 ...

随机推荐

  1. POJ-1459(最大流+EK算法)

    Power Network POJ-1459 这题值得思索的就是特殊的输入,如何输入一连串字符.这里采用的方法是根据输入已知的输入格式,事先预定好要接受的数据类型. 这里套用的板子也是最大流的模板,但 ...

  2. springboot注解之@Configuration 和 @Bean

    1.包结构 2.主程序类 1 /** 2 * 主程序类 3 * @SpringBootApplication:这是一个springboot应用 4 * 5 * @SpringBootApplicati ...

  3. python学习之基础内容

    python基础内容① 什么是python? -一种计算机语言,计算机语言分为 -高级语言:python.java.Ruby.C#.C++...... -基础语言:C语言.汇编 -计算机可以直接执行基 ...

  4. Python装饰器(3)

    这篇文章中记录说明下多个装饰器一同装饰同一个函数时的执行顺序问题. [装饰器链] 按照惯例,先看代码示例: import time def debug1(str): #传参接受类的方法 def fun ...

  5. python多线程参考文章

    1. https://www.jianshu.com/p/c93e630d8089 2.https://www.runoob.com/python/python-multithreading.html ...

  6. 数字转人民币读法-python3

    """ 2 把一个浮点数分解成证书备份和小数部分 3 """ 4 def divide(num): 5 intnum = int(num) ...

  7. 《逆向工程核心原理》——API HOOK

    编写dll处理hook逻辑,注入到目标进程,实现api hook. Windows10 notepad,通过hook kernel32.dll.WriteFile,实现小写字母转大写保存到文件. ho ...

  8. 四、MYSQL数据练习题

    我的MYSQL版本是mysql-5.7.24-winx64,每天练习5道习题. 如果有错误或者更优的解决方法,欢迎大家指出,谢谢!! 一.测试表格 --1.学生表Student(Sid,Sname,S ...

  9. 云原生 API 网关,gRPC-Gateway V2 初探

    gRPC-Gateway 简介 我们都知道 gRPC 并不是万能的工具. 在某些情况下,我们仍然想提供传统的 HTTP/JSON API.原因可能从保持向后兼容性到支持编程语言或 gRPC 无法很好地 ...

  10. 一文搞懂MySQL体系架构!!

    写在前面 很多小伙伴工作很长时间了,对于MySQL的掌握程度却仅仅停留在表面的CRUD,对于MySQL深层次的原理和技术知识了解的少之又少,随着工作年限的不断增长,职场竞争力却是不断降低的.很多时候, ...