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;
}
浙公网安备 33010602011771号