You have been given a matrix C N*M, each element E of C N*M is positive and no more than 1000, The problem is that if there exist N numbers a1, a2, … an and M numbers b1, b2, …, bm, which satisfies that each elements in row-i multiplied with ai and each elements in column-j divided by bj, after this operation every element in this matrix is between L and U, L indicates the lowerbound and U indicates the upperbound of these elements.

InputThere are several test cases. You should process to the end of file. 
Each case includes two parts, in part 1, there are four integers in one line, N,M,L,U, indicating the matrix has N rows and M columns, L is the lowerbound and U is the upperbound (1<=N、M<=400,1<=L<=U<=10000). In part 2, there are N lines, each line includes M integers, and they are the elements of the matrix.

OutputIf there is a solution print "YES", else print "NO".Sample Input

3 3 1 6
2 3 4
8 2 6
5 2 9

Sample Output

YES
 

题意:问是否满足每行乘一个相同的正实数,然后每一列除一个相同的正实数,使得矩阵李每一个数在[L,U]内。

思路:化简后是带系数的不等系组,L*Bj<=X*Ai<=U*Bj,那么取对数即可,把Ai和Bj的系数化为1,然后差分约束即可。

1,是求是否可行,而不是求最大最小。所以用最长路判正环也行,用最短路判负环亦可。因为如过不可行,那么既无最大,也没有最小;而如果有可行解,那么既有最大,又有最小。

2,判环的时候如果按进队次数大于n+m时时退出会超时,所以加了qsrt,虽然我不知道这样是否科学。。。存疑。

3,本题自己限定了正数,方便求解,也避免负时不等号要改变方向。

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
const double inf=0x7fffffff;
int Laxt[maxn],Next[maxn<<],To[maxn<<];
int vis[maxn],inq[maxn],cnt,n,m;
double dis[maxn],Len[maxn<<];
void update()
{
cnt=;
memset(Laxt,,sizeof(Laxt));
memset(vis,,sizeof(vis));
memset(inq,,sizeof(inq));
}
void add(int u,int v,double d)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
Len[cnt]=d;
}
bool spfa()
{
int times=;
for(int i=;i<=n+m;i++) dis[i]=-inf;
queue<int>q;
q.push(); dis[]=; inq[]=;
while(!q.empty()){
if(times>*(n+m)) return false;
int u=q.front(); q.pop(); inq[u]=;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i];
if(dis[v]<dis[u]+Len[i]){
dis[v]=dis[u]+Len[i];
if(!inq[v]){
inq[v]=; vis[v]++; q.push(v); times++;
if(vis[v]>sqrt(n+m)) return false;
}
}
}
} return true;
}
int main()
{
int i,j; double x,L,U;
while(~scanf("%d%d%lf%lf",&n,&m,&L,&U)){
update();
L=log10(L);U=log10(U);
for(i=;i<=n;i++)
for(j=;j<=m;j++){
scanf("%lf",&x);
add(n+j,i,L-log10(x));
add(i,n+j,-U+log10(x));
}
for(i=;i<=n+m;i++) add(,i,);
if(spfa()) printf("YES\n");
else printf("NO\n");
} return ;
}
//1,知道要去对数;2,判定时的投机取巧。

最新文章

  1. Linux 查看端口被占用情况
  2. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.6.Dialog控件
  3. HDU 4035 Maze 概率dp,树形dp 难度:2
  4. UVa 11134 (区间上的贪心) Fabled Rooks
  5. PL/pgSQL RETURNS TABLE 例子
  6. Populating Next Right Pointers in Each Node II
  7. 安装ejabberd2并配置MySQL为其数据库
  8. droppable的详细参数讲解
  9. SQL Server索引进阶:第七级,过滤的索引
  10. Windows VS下搭建cocos2d-x环境搭建
  11. 中介模式和学习日记Effective C++
  12. Ubuntu17.10下启动Rancher
  13. 下载android5.0源码
  14. 【译文】CSS技术:如何正确的塑造button样式!
  15. 逻辑卷管理(linux)
  16. ArcGIS JavaScript开发过程中,底图产生拼接缝问题
  17. 你应该这样理解JVM内存管理
  18. 大一下第2次作业(markdown改)
  19. 第16课 右值引用(3)_std::forward与完美转发
  20. [Robot Framework] 搭建Robot Framework和RIDE(Robot Framework GUI) 的环境

热门文章

  1. cocos2d-x step by step(3) Double Kill
  2. python的私有化
  3. (学习笔记3)BMP位图的读取与显示
  4. python(15)- 装饰器及装饰器的使用
  5. windows xp下mysql5.0安装
  6. windows下redis安装以及简单配置
  7. Zoj2421 广搜
  8. PHP中使用Redis
  9. Html调用 QQ接口
  10. C语言宏定义时#(井号)和##(双井号)作用