bzoj3436: 小K的农场(差分约束)
3436: 小K的农场
题目:传送门
题解:
查分基础:
t==1 a>=b+c
t==2 b>=a-c
t==3 a>=b+0 b>=a+0
跑最长路一A
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 int n,m; 8 struct node 9 { 10 int x,y,d,next; 11 }a[21000];int len,last[21000]; 12 void ins(int x,int y,int d) 13 { 14 len++;a[len].x=x;a[len].y=y;a[len].d=d; 15 a[len].next=last[x];last[x]=len; 16 } 17 18 bool v[21000];int d[21000],ru[21000],list[21000]; 19 int main() 20 { 21 scanf("%d%d",&n,&m); 22 for(int i=1;i<=m;i++) 23 { 24 int t,x,y,d; 25 scanf("%d%d%d",&t,&x,&y); 26 if(t==1)scanf("%d",&d),ins(y,x,d); 27 if(t==2)scanf("%d",&d),ins(x,y,-d); 28 if(t==3)ins(x,y,0),ins(y,x,0); 29 } 30 for(int i=1;i<=n;i++)d[i]=1; 31 int head=0;for(int i=n;i>=0;i--)list[++head]=i; 32 memset(v,0,sizeof(v));memset(ru,0,sizeof(ru)); 33 bool bk=true; 34 while(head!=0) 35 { 36 int x=list[head--];v[x]=true; 37 for(int k=last[x];k;k=a[k].next) 38 { 39 int y=a[k].y; 40 if(d[y]<d[x]+a[k].d) 41 { 42 d[y]=d[x]+a[k].d; 43 ru[y]++;if(ru[y]==n+1){bk=false;break;} 44 if(v[y]==true)v[y]=false,list[++head]=y; 45 } 46 } 47 if(bk==false)break; 48 } 49 if(bk==true)printf("Yes\n"); 50 else printf("No\n"); 51 return 0; 52 }