取对数将乘除转化为加减。
L<=m[i][j]*a[i]/b[j]<=U
log(L/m[i][j])<=log(a[i])-log(b[j])<=log(U/m[i][j])
则 :
log(a[i])<=log(b[j])+log(U/m[i][j])
log(b[j])<=log(a[i])+log(m[i][j]/L)
还是没什么区别,简单的见图,spfa
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int oo=1e8; 8 const int mn=161000; 9 const int mm=961000; 10 int edge,n,m; 11 double l,u; 12 int ver[mm],next[mm]; 13 double dis[mn],cost[mm]; 14 int head[mn],vis[mn],q[mn],outque[mn]; 15 void addedge(int u,int v,double c) 16 { 17 ver[edge]=v,cost[edge]=c,next[edge]=head[u],head[u]=edge++; 18 } 19 bool spfa() 20 { 21 int i,u,v,l,r=0; 22 double tmp; 23 for(i=1;i<=n+m;i++) dis[i]=oo,vis[i]=1,outque[i]=0,q[r++]=i; 24 dis[1]=0; 25 for(l=0;l!=r;(++l>mn)?l=0:l) 26 for(i=head[u=q[l]],vis[u]=0;i>=0;i=next[i]) 27 if(dis[v=ver[i]]>(tmp=dis[u]+cost[i])) 28 { 29 dis[v]=tmp; 30 if(vis[v]) continue; 31 if(++outque[v]>(int)sqrt((n+m)*1.0)) return false; 32 vis[q[r++]=v]=1; 33 if(r>=mn) r=0; 34 } 35 return true; 36 } 37 int main() 38 { 39 int x,i,j; 40 while(~scanf("%d%d%lf%lf",&n,&m,&l,&u)) 41 { 42 edge=0; 43 memset(head,-1,sizeof(head)); 44 for(i=1;i<=n;i++) 45 for(j=1;j<=m;j++) 46 { 47 scanf("%d",&x); 48 addedge(j+n,i,log10(double(u/x))); 49 addedge(i,j+n,log10(double(x/l))); 50 } 51 if(spfa()) puts("YES"); 52 else puts("NO"); 53 } 54 }