http://acm.hdu.edu.cn/showproblem.php?pid=3666
差分约束,关键在于找不等式,然后建图
这个题 spfa 判断负环时,如果以更新次数大于等于N判断有负环,会超时
只要判断更新次数大于sqrt(N)就可以,原理不知道
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<string> #include<set> #include<map> #include<cmath> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<stack> //#define ull unsigned long long using namespace std; const int INF=0x3f3f3f3f; const int MOD=1000000007; const double eps=1e-6; const int N=10005; const int M=1000005; int head[N],I; struct node { int j,next; double d; }edge[M]; double dist[N]; queue<int>qt; bool had[N]; int in[N]; void add(int i,int j,double d) { edge[I].j=j; edge[I].d=d; edge[I].next=head[i]; head[i]=I++; } bool spfa(int n) { while(!qt.empty()) qt.pop(); for(int i=0;i<n;++i) { dist[i]=0.0; had[i]=true; in[i]=1; qt.push(i); } while(!qt.empty()) { int x=qt.front(); qt.pop(); had[x]=false; for(int t=head[x];t!=-1;t=edge[t].next) { int j=edge[t].j; if(dist[j]>dist[x]+edge[t].d) { dist[j]=dist[x]+edge[t].d; if(!had[j]) { had[j]=true; ++in[j]; qt.push(j); if(in[j]>sqrt(1.0*n)) return false; } } } } return true; } void init(int n,int m,double L,double U) { memset(head,-1,sizeof(head));I=0; for(int i=0;i<n;++i) for(int j=0;j<m;++j) { double ftmp; scanf("%lf",&ftmp); add(i,j+n,log(ftmp/L)); add(j+n,i,log(U/ftmp)); } } int main() { //freopen("data.in","r",stdin); int n,m; double L,U; while(scanf("%d %d %lf %lf",&n,&m,&L,&U)!=EOF) { init(n,m,L,U); if(spfa(n+m)) printf("YES\n"); else printf("NO\n"); } return 0; }