题意:

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

思路:

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

目就是不但要求满流,某些点还有上限制,或者下限制,那么就直接是上下流呗,对了还有一个地方提醒一下,在建图之前判断一下有没有输入数据冲突的情况,下面说关键部分,也就是建图,建图之前定义几个变量,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. Springboot的监控

    目录 Micrometer 计数器 仪表 摘要 计时器 Prometheus grafana 保存后我们就能在dashboard上看得我我们的监控指标了参考 Spring Boot有个子项目Sprin ...

  2. 我与FreeBSD 的故事之二

    那些人的丑恶嘴脸使我发笑,我愈发远离所谓的社区与论坛.电视剧<武林外传>说的好:有人的地方就有江湖,江湖从未走远,从未改变.社区中的冲突很少是技术层面的,按照老话说睿智的人很少发表自己的见 ...

  3. 如何对shell脚本中斜杠进行转义?

    1.在编写shell脚本时,经常会遇到对某个路径进行替换,而路径中包含斜杠(/),此时我们就需要对路径中涉及的斜杠进行转义,否则执行失败.具体示例如下: 需求描述: 将sjk目录下的test文件中的p ...

  4. Java8的新特性--Optional

    目录 Optional 一.Optional类是什么? 二.Optional类常用的方法 1. 创建Optional实例 1.1 Optional.of(T) 1.2 Optional.empty() ...

  5. ch1_6_3求解移动字符串问题

    import java.util.Scanner; public class ch1_6_3求解移动字符串问题 { public static void main(String[] args) { / ...

  6. frida hook_RegisterNatives--使用frida打印so中动态注册的函数

    原文地址:https://github.com/lasting-yang/frida_hook_libartfrida -U --no-pause -f package_name -l hook_Re ...

  7. 4、MyBatis教程之配置解析

    5.配置解析 核心配置文件 mybatis-config.xml 系统核心配置文件 MyBatis 的配置文件会深深影响 MyBatis 行为的设置和属性信息. 能配置的内容如下: configura ...

  8. 【框架】SPI四种模式+通用设备驱动实现-源码

    目录 前言 bsp_spi.c bsp_spi.h bsp_flash.c bsp_flash.h 前言 SPI 介绍为搜集百度资料+个人理解 其余为原创(有误请指正) 集四种模式于一身 demo 采 ...

  9. 计算机体系结构——CH2 指令系统

    CH2 指令系统 右键点击查看图像,查看清晰图像 X-mind CH2 指令系统 数据表示 定义 指计算机硬件能够直接识别,可以被指令系统直接调用的那些数据类型 确定哪些数据类型用哪些数据表示实现,是 ...

  10. 截取pod ip地址最后一列

    资源清单: --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: init-demo namespace: test ...