由题目得不等式 L<=(c[i][j]*a[i])/b[j]<=U 然后卡在这了... 对于除法可以左右同取log转换为减法 实在是菜......
然后就是差分约束模板 只不过这里我们不用再考虑每一个点(loga[i]或logb[j])的具体取值 因为题目只要求判是否可行 只判正负环即可 所以不必纠结源点的取值
#include <cstdio>
#include <cmath>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int v;
double w;
int next;
};
stack <int> stk;
node edge[400010];
double dis[1010];
int first[1010],book[1010],cnt[1010];
int n,m,num,l,r;
void addedge(int u,int v,double w)
{
edge[num].v=v;
edge[num].w=w;
edge[num].next=first[u];
first[u]=num++;
return;
}
bool spfa()
{
double w;
int i,u,v;
while(!stk.empty()) stk.pop();
for(i=1;i<=n+m;i++)
{
dis[i]=1000000000.0;
book[i]=0;
cnt[i]=0;
}
stk.push(1);
dis[1]=0.0,book[1]=1,cnt[1]=1;
while(!stk.empty())
{
u=stk.top();
stk.pop();
book[u]=0;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v,w=edge[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!book[v])
{
stk.push(v);
book[v]=1,cnt[v]++;
if(cnt[v]>n+m) return false;
}
}
}
}
return true;
}
int main()
{
double x,y;
int i,j,val;
bool res;
while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF)
{
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&val);
x=r,y=val;
addedge(i,n+j,log(x/y));
x=val,y=l;
addedge(n+j,i,log(x/y));
}
}
res=spfa();
if(res) printf("YES\n");
else printf("NO\n");
}
return 0;
}