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 }

 

posted @ 2018-03-03 11:38  CHerish_OI  阅读(213)  评论(0编辑  收藏  举报