正题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3666
题目大意
一个n∗mn*mn∗m的矩阵CCC求有没有一个长度为nnn的aaa序列和一个长度为mmm的bbb序列使得
L≤Ci,j∗ai/bi≤RL\leq C_{i,j}*a_i/b_i\leq RL≤Ci,j∗ai/bi≤R
解题思路
首先我们将乘除转换为自然对数。
所以要求变为
log(L)≤log(ci,j)+log(ai)−log(bi)≤log(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)
然后我们分开两段并转换为差分约束形式
log(ai)−log(bi)≥log(L)−log(ci,j)log(a_i)-log(b_i)\geq log(L)-log(c_{i,j})log(ai)−log(bi)≥log(L)−log(ci,j)
andandand
log(ai)−log(bi)≥−log(R)+log(ci,j)log(a_i)-log(b_i)\geq -log(R)+log(c_{i,j})log(ai)−log(bi)≥−log(R)+log(ci,j)
然后跑差分约束
codecodecode
#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");}
}