(1)思路:
将不等式化简L<=xij*(ai/bj)<=R
L/xij <= ai/bj <= R/xij
将两边开log
log(L) - log(xij) <= log(ai) - log(bj) <= log(R) -log (xij)
所以可以得到
db - da <= log(xij) - log(L)
da - db <= log(R) - log(xij)
所以更新得到最短路,判读是否存在环,如果存在环就不存在。
扫描二维码关注公众号,回复:
6534612 查看本文章
(2)代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 1e5+10;
const double INF = 1e9+10;
int vis[maxn],m,n,que[maxn<<2],tim[maxn],head[maxn],tot;
double dis[maxn],L,U;
struct Node{
int v,nxt;
double w;
}cur[maxn<<2];
void Init(){
memset(head,-1,sizeof(head));
tot = 0;
}
void Add(int x,int y,double z){
cur[tot].v = y;
cur[tot].nxt = head[x];
cur[tot].w = z;
head[x] = tot++;
}
bool spfa(){
for(int i=1;i<=n+m;i++){
vis[i] = 0;dis[i] = INF;tim[i] = 0;
}
dis[1] = 0;
int top = 0;
que[top++] = 1;tim[1]++;
while(top!=0){
int x = que[--top];vis[x] = 0;
for(int i=head[x];i!=-1;i=cur[i].nxt){
int y = cur[i].v;
if(dis[y]>dis[x]+cur[i].w){
dis[y] = dis[x]+cur[i].w;
if(vis[y]==0){
vis[y] = 1;
que[top++] = y;
if(++tim[y]>n+m+1) return false;
}
}
}
}
return true;
}
int main(void){
while(~scanf("%d%d%lf%lf",&n,&m,&L,&U)){
Init();
L = log2(L);U = log2(U);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
double tp;scanf("%lf",&tp);
tp = log2(tp);
int x = i,y = j+n;
Add(x,y,tp-L);
Add(y,x,U-tp);
}
}
if(spfa()==true) printf("YES\n");
else printf("NO\n");
}
return 0;
}