正题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3666
题目大意
一个
n
∗
m
n*m
n∗m的矩阵
C
C
C求有没有一个长度为
n
n
n的
a
a
a序列和一个长度为
m
m
m的
b
b
b序列使得
L
≤
C
i
,
j
∗
a
i
/
b
i
≤
R
L\leq C_{i,j}*a_i/b_i\leq R
L≤Ci,j∗ai/bi≤R
解题思路
首先我们将乘除转换为自然对数。
所以要求变为
l
o
g
(
L
)
≤
l
o
g
(
c
i
,
j
)
+
l
o
g
(
a
i
)
−
l
o
g
(
b
i
)
≤
l
o
g
(
R
)
log(L)\leq log(c_{i,j})+log(a_i)-log(b_i)\leq log(R)
log(L)≤log(ci,j)+log(ai)−log(bi)≤log(R)
然后我们分开两段并转换为差分约束形式
l
o
g
(
a
i
)
−
l
o
g
(
b
i
)
≥
l
o
g
(
L
)
−
l
o
g
(
c
i
,
j
)
log(a_i)-log(b_i)\geq log(L)-log(c_{i,j})
log(ai)−log(bi)≥log(L)−log(ci,j)
a
n
d
and
and
l
o
g
(
a
i
)
−
l
o
g
(
b
i
)
≥
−
l
o
g
(
R
)
+
l
o
g
(
c
i
,
j
)
log(a_i)-log(b_i)\geq -log(R)+log(c_{i,j})
log(ai)−log(bi)≥−log(R)+log(ci,j)
然后跑差分约束
c o d e code code
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1100;
const double inf=0x3f3f3f3f;
struct node{
int to,next;
double w;
}a[N*N];
int n,m,ls[N],tot;
bool v[N];
double f[N],L,R;
void addl(int x,int y,double w)
{
a[++tot].to=y;
a[tot].w=w;
a[tot].next=ls[x];
ls[x]=tot;
}
bool spfa()
{
int cnt=0;
memset(v,0,sizeof(v));
queue<int> q;
for(int i=1;i<=n+m+10;i++)
f[i]=inf;
q.push(1);f[1]=0;v[1]=1;
while(!q.empty())
{
int x=q.front();v[x]=0;q.pop();
if(++cnt>2*(n+m))
return 0;
for(int i=ls[x];i;i=a[i].next)
{
int y=a[i].to;
if(f[x]+a[i].w<f[y])
{
f[y]=f[x]+a[i].w;
if(!v[y]){
q.push(y);
v[y]=1;
}
}
}
}
return 1;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%lf%lf",&L,&R);
memset(ls,0,sizeof(ls));tot=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
double x;
scanf("%lf",&x);
addl(i,j+n,log2(x)-log2(L));
addl(j+n,i,log2(R)-log2(x));
}
if(spfa()) puts("YES");
else puts("NO");
}
}