思路:鉴定为——负环裸题。
注意:多测试样例,且题目没有说一个农场之内的所有田地都能互相到达,所以要把所有点入队。
至于为什么距离一开始可以初始化为0,因为图里面存在负环和负权边的情况下不管初始化为什么,最后负环上的都会变成负无穷。
- #include
- #include
- #include
- #include
- using namespace std;
- typedef long long ll;
- const int N=1e3,M=6e3;
- int e[M],ne[M],h[N],w[M],idx;
- int dist[N];
- int q[N];
- bool st[N];
- int cnt[N];
- int n,m,w1;
- void add(int a,int b,int c)
- {
- e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
- }
- bool spfa()
- {
- int hh=0,tt=0;
- memset(dist,0,sizeof dist);
- memset(st,0,sizeof st);
- memset(cnt,0,sizeof cnt);
- for(int i=1;i<=n;i++)
- {
- q[tt++]=i;
- st[i]=true;
- }
- while(hh!=tt)
- {
- int t=q[hh++];
- if(hh==N)hh=0;
- st[t]=false;
- for(int i=h[t];~i;i=ne[i])
- {
- int j=e[i];
- if(dist[j]>dist[t]+w[i])
- {
- dist[j]=dist[t]+w[i];
- cnt[j]=cnt[t]+1;
- if(cnt[j]>=n)return true;
- if(!st[j])
- {
- q[tt++]=j;
- if(tt==N) tt=0;
- st[j]=true;
- }
- }
- }
- }
- return false;
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--)
- {
- scanf("%d%d%d",&n,&m,&w1);
- memset(h,-1,sizeof h);
- idx=0;
- for(int i=1;i<=m;i++)
- {
- int a,b,c;
- scanf("%d%d%d",&a,&b,&c);
- add(a,b,c);
- add(b,a,c);
- }
- for(int i=1;i<=w1;i++)
- {
- int a,b,c;
- scanf("%d%d%d",&a,&b,&c);
- add(a,b,-c);
- }
- if(spfa())puts("YES");
- else puts("NO");
- }
- return 0;
- }
- //I LOVE YOU