题意:

      和hdu4888一样,只不过是数据加强了,就是给你行列的和,让你构造一个矩阵,然后判断矩阵是否唯一。

思路:

      构造矩阵很简单,跑一次最大流就行了,关键是判断矩阵的唯一性,之前的那个4888我用的是深搜找环过的,这个题目就TLE了,数据加强了,对于判断矩阵的唯一性我们可以这么想假如某一行的i列和j列满足 i列的这个> 0 && j列的这个 < 9此时我们再在另一行找到   i列的这个< 9 && j列的这个 > 0就可以把>0 的拿出来一个放在<9的上面,这样答案就不唯一了,对于最大流跑完后的到的矩阵,如果我们暴力判断上面的哪些情况的话是大约O(n^4)这样就比DFS找环还浪费时间,所以我们要用到dp优化,dp[i][j]记录的是在当前的状态之前,是否存在在某一行中,i列<9,j列>0,这样我们就可以利用之前状态的结果来节省一层for(具体看代码),但是这样还是TLE了,我们在每个for前面加几个小优化就可以过了。


#include<stdio.h>
#include<string.h>
#include<queue> #define N_node 1005
#define N_edge 600000
#define INF 1000000000

using namespace
std; typedef struct
{
int
to ,next ,cost;
}
STAR; typedef struct
{
int
t ,x;
}
DEP; STAR E[N_edge];
DEP xin ,tou;
int
list[N_node] ,listt[N_node] ,tot;
int
deep[N_node];
int
row[505] ,col[505];
int
map[505][505];
int
dp[505][505]; void add(int a ,int b ,int c)
{

E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot; E[++tot].to = a;
E[tot].cost = 0;
E[tot].next = list[b];
list[b] = tot;
} bool
BFS_Deep(int s ,int t ,int n)
{

memset(deep ,255 ,sizeof(deep));
deep[s] = 0;
xin.x = s ,xin.t = 0;
queue<DEP>q;
q.push(xin);
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
minn(int x ,int y)
{
return
x < y ? x : y;
} 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(
flow == nowflow)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 ,int mktot)
{ int
i = 1 ,j = 1 ,k;
for(
k = mktot + 1 ;k <= tot ;k += 2)
{

map[i][j] = E[k].cost;
if(++
j > m) {i ++ ,j = 1;}
}

memset(dp ,0 ,sizeof(dp));
for(
i = 1 ;i <= n ;i ++)
{
if(
row[i] == 0 || m * 9 == row[i])continue;
for(
j = 1 ;j <= m ;j ++)
{
if(
col[j] == 0 || n * 9 == col[j])continue;
for(
k = j + 1 ;k <= m ;k ++)
{
int
mk1 = 0 ,mk2 = 0;
if(
map[i][j] < 9 && map[i][k] > 0)
{
if(
dp[k][j]) return 1;
mk1 ++;
}
if(
map[i][j] > 0 && map[i][k] < 9)
{
if(
dp[j][k]) return 1;
mk2 ++;
}
if(
mk1) dp[j][k] = 1;
if(
mk2) dp[k][j] = 1;
}
}
}
return
0;
} int main ()
{
int
n ,m ,i ,j ,s1 ,s2 ,a ,mkk;
int
t ,cas = 1;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d %d" ,&n ,&m);
s1 = s2 = mkk = 0;
memset(list ,0 ,sizeof(list)) ,tot = 1;
for(
i = 1 ;i <= n ;i ++)
{

scanf("%d" ,&a);
add(0 ,i ,a);
s1 += a;
if(
m * 9 < a) mkk = 1;
row[i] = a;
}
for(
i = 1 ;i <= m ;i ++)
{

scanf("%d" ,&a);
add(i + n ,n + m + 1 ,a);
s2 += a;
col[i] = a;
if(
n * 9 < a) mkk = 1;
}

printf("Case #%d: " ,cas ++);
if(
s1 != s2 || mkk)
{

puts("So naive!");
continue;
}
int
mktot = tot + 1;
for(
i = 1 ;i <= n ;i ++)
for(
j = 1 ;j <= m ;j ++)
add(i ,j + n ,9);
int
maxflow = DINIC(0 ,n + m + 1 ,n + m + 1);
if(
s1 != maxflow)
{

puts("So naive!");
continue;
}

jude(n ,m ,mktot)? puts("So young!"):puts("So simple!");
}
return
0;
}

hdu4975 行列和构造矩阵(dp判断唯一性)的更多相关文章

  1. hdu4975 网络流解方程组(网络流+dfs判环或矩阵DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4975 A simple Gaussian elimination problem. Time Limit: 20 ...

  2. hdu 4975 最大流解决行列和求矩阵问题,用到矩阵dp优化

    //刚开始乱搞. //网络流求解,如果最大流=所有元素的和则有解:利用残留网络判断是否唯一, //方法有两种,第一种是深搜看看是否存在正边权的环,见上一篇4888 //至少四个点构成的环,第二种是用矩 ...

  3. [数学-构造矩阵]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的公式!!! ...

  4. POJ 2396 构造矩阵(上下流)

    题意:       要求构造一个矩阵,给你行和,列和,还有一些点的上下范围,输出一个满足题意的矩阵. 思路:       这个题目很经典,这是自己看上下流后接触的第一道题,感觉很基础的一道题目,现在我 ...

  5. hdu4888 最大流(构造矩阵)

    题意:       让你构造一个矩阵,满足每一行的和,和每一列的和都等于他给的,还要判断答案是否唯一,还有一点就是矩阵内所有的数字都是[0,k]范围的. 思路:       这个题目看完就让我想起了h ...

  6. 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. ...

  7. Number Sequence(HDU 1005 构造矩阵 )

    Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

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

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

  9. hdu 4975 最大流问题解决队伍和矩阵,利用矩阵dp优化

    //刚開始乱搞. //网络流求解,假设最大流=全部元素的和则有解:利用残留网络推断是否唯一, //方法有两种,第一种是深搜看看是否存在正边权的环.见上一篇4888 //至少四个点构成的环,另外一种是用 ...

随机推荐

  1. Java 集合框架 03

    集合框架·HashSet 和 TreeSet HashSet存储字符串并遍历 * A:Set集合概述及特点 * 通过API查看即可 * 无索引,不可以重复,无序 * B:案例演示 * HashSet存 ...

  2. 扫盲贴|如何评价一款App的稳定性和质量?

    作者:友盟+移动开发专家 张文 「崩溃」与「卡顿」.「异常退出」等一样,是影响App稳定性常见的三种情况.相关数据显示,当iOS的崩溃率超过0.8%,Android的崩溃率超过0.4%的时候,活跃用户 ...

  3. Windows下的Linux子系统

    强调!!!必须是Windows专业版!!! 一.安装运行过程 第一步:打开开发人员模式 第二步:进入 '控制面板 '--'程序'--'启用的Windows功能'--勾选Linux子系统(根据提示进行重 ...

  4. socket 之send和recv原理剖析

    认识TCP socket的发送缓冲区和接收缓冲区 当创建一个TCP socket对象的时候会有一个发送缓冲区和一个接收缓冲区,相当与内存中的一片空间 send原理剖析 send是不是直接把数据发送给服 ...

  5. 从零学脚手架(八)---webpack-dev-server源码分析

    上一篇中介绍了webpack-dev-server属性配置 这一篇就简单的梳理下webpack-dev-server内部实现. 由于涉及到源码解析,所以会涉及到一些比较难啃的知识,我会尽量进行简单化描 ...

  6. InfluxDB、Grafana等开源软件的监控后门

    在使用手机APP的过程中,用户信息会不知不觉的被APP悄无声息的收集到云端,然后进行各种用户行为分析以及智能推荐,这是众所周知但秘而不宣的事. 在使用开源软件时,也存在悄悄收集用户使用信息,并且上报到 ...

  7. 为了效率,我们可以用的招数 之 strlen

    如果要你写一个计算字符串长度的函数 strlen,应该怎么写?相信你很容易写出如下实现: 1 int strlen_1(const char* str) { 2 int cnt = 0; 3 4 if ...

  8. 【面试技巧】老生常谈之 n 种使用 CSS 实现三角形的技巧

    在一些面经中,经常能看到有关 CSS 的题目都会有一道如何使用 CSS 绘制三角形,而常见的回答通常也只有使用 border 进行绘制一种方法. 而 CSS 发展到今天,其实有很多有意思的仅仅使用 C ...

  9. leetcode 783 二叉搜索树节点最小距离

    PS:(感觉这题名字和内容有歧义) 要求得到任意不同节点值之间的最小差值. 本身二叉树是有序的,又找最小差值,其实就是相当于在一个有序数组中找到每相邻两数之间最小差值. 朴素思想: 中序遍历树,把值都 ...

  10. leetcode 刷题(数组篇)11题 盛最多水的容器(双指针)

    题目描述 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) .找出其 ...