#差分約束,SPFA#洛谷 1993 小 K 的農場
阿新 • • 發佈:2020-08-18
分析
對於描述1,也就是\((a,b,-c)\),\(b\)比\(a\)至多多\(-c\)
對於描述2,也就是\((b,a,c)\),\(a\)比\(b\)至多多\(c\)
對於描述3,也就是\((a,b,0),(b,a,0)\)
用SPFA判負環就可以了
程式碼
#include <cstdio> #include <cctype> #include <deque> #include <cstring> #define rr register using namespace std; const int N=5011; deque<int>q; struct node{int y,w,next;}e[N*3]; int as[N],dis[N],cNt[N],v[N],n,k,m; inline signed iut(){ rr int ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } inline void add(int x,int y,int w){e[++k]=(node){y,w,as[x]},as[x]=k;} signed main(){ n=iut(),m=iut(); memset(as,-1,sizeof(as)); for (rr int i=1;i<=n;++i) add(0,i,0); for (rr int i=1;i<=m;++i){ rr int op=iut(),x=iut(),y=iut(); if (op==1) add(x,y,-iut()); else if (op==2) add(y,x,iut()); else add(x,y,0),add(y,x,0); } memset(dis,0x3f,sizeof(dis)); q.push_back(0),dis[0]=0,v[0]=1; while (q.size()){ rr int x=q.front(); q.pop_front(); for (rr int i=as[x];~i;i=e[i].next) if (dis[e[i].y]>dis[x]+e[i].w){ dis[e[i].y]=dis[x]+e[i].w; if (++cNt[e[i].y]==n&&e[i].w<0) return !printf("No"); if (!v[e[i].y]){ v[e[i].y]=1; if (q.size()&&dis[e[i].y]<dis[q.front()]) q.push_front(e[i].y); else q.push_back(e[i].y); } } v[x]=0; } return !printf("Yes"); }