【差分约束系统/DFS版SPFA】BZOJ3436-小K的农场

【题目大意】

总共n个农场,有以下三种描述:农场a比农场b至少多种植了c个单位的作物,农场a比农场b至多多种植了c个单位的作物,农场a与农场b种植的作物数一样多。问是否有可能性。

【思路】

农场a比农场b至少多种植了c个单位的作物:a>=b+c → b<=a-c,由a向b连一条-c的边。

农场a比农场b至多多种植了c个单位的作物:a<=b+c,由b向a连一条c的边。

农场a与农场b种植的作物数一样多:a=b → b<=a<=b,互相连一条0的边。

SPFA判断负环,要用DFS版本的来。DFS版本的直接参考了rausen学长的……真是快到飞起(;′⌒`)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=10000+50;
 4 struct edge
 5 {
 6     int to,len;
 7 };
 8 int n,m;
 9 vector<edge> E[MAXN];
10 int vis[MAXN],dis[MAXN],flag;
11 
12 void addedge(int u,int v,int w)
13 {
14     E[u].push_back((edge){v,w});
15 }
16 
17 void init()
18 {
19     scanf("%d%d",&n,&m);
20     for (int i=1;i<=m;i++)
21     {
22         int op,a,b,c;
23         scanf("%d",&op);
24         if (op==1)//a-b>=c
25         {
26             scanf("%d%d%d",&a,&b,&c);
27             addedge(a,b,-c);
28         }
29         if (op==2)
30         {
31             scanf("%d%d%d",&a,&b,&c);
32             addedge(b,a,c);
33         }
34         if (op==3)
35         {
36             scanf("%d%d",&a,&b);
37             addedge(a,b,0);addedge(b,a,0);
38         }
39     }
40 }
41 
42 void spfa(int fr)
43 {
44     if (vis[fr])
45     {
46         flag=1;
47         return;
48     }
49     vis[fr]=1;
50     for (int i=0;i<E[fr].size();i++)
51     {
52         int to=E[fr][i].to,len=E[fr][i].len;
53         if (dis[fr]+len<dis[to])
54         {
55             dis[to]=dis[fr]+len;
56             spfa(to);
57             if (flag) return;
58         }
59     }
60     vis[fr]=0;
61 }
62 
63 void solve()
64 {
65     memset(vis,0,sizeof(vis));
66     for (int i=1;i<=n;i++)
67     {
68         spfa(i);
69         if (flag) break;
70     }
71     puts(flag?"No":"Yes");
72 }
73 
74 int main()
75 {
76     init();
77     solve();
78     return 0;
79 } 
原文地址:https://www.cnblogs.com/iiyiyi/p/6057814.html