2015-01-07 21:18:11

思路:差分约束水题?.....写了好久啊!(之前老不过...后来怒写了3个版本)

  根据要求建图即可,跑最长路/最短路都行。由于图可能是不连通的,所以方法1:建立超级起点,与0~n所有点建立0权边。方法2:对有所点跑一遍最短路(可以初始把所有点放入队列。)

  如果跑最短路:对于约束一:S(i + j) - S(i - 1) > C --> S(a - 1) <= S(a + b) - (C + 1)

          对于约束二:S(i + j) - S(a - 1) < C --> S(i + j) <= S(a - 1) + (C - 1)

  然后用bellman-ford / spfa 判负环都可。(spfa的dfs版应该更快)

(1)spfa(bfs)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 #define lp (p << 1)
14 #define rp (p << 1|1)
15 #define getmid(l,r) (l + (r - l) / 2)
16 #define MP(a,b) make_pair(a,b)
17 typedef long long ll;
18 typedef unsigned long long ull;
19 typedef pair<int,int> pii;
20 const int INF = (1 << 30) - 1;
21 const int maxn = 110;
22 
23 int n,m;
24 int first[maxn],ecnt;
25 int cnt[maxn],inq[maxn],dis[maxn];
26 
27 struct edge{
28     int v,next,cost;
29 }e[maxn << 1];
30 
31 bool Spfa(int s){
32     queue<int> Q;
33     memset(inq,0,sizeof(inq));
34     memset(cnt,0,sizeof(cnt));
35     fill(dis,dis + n + 1,INF);
36     inq[s] = cnt[s] = 1;
37     dis[s] = 0;
38     Q.push(s);
39     while(!Q.empty()){
40         int x = Q.front(); Q.pop();
41         inq[x] = 0;
42         for(int i = first[x]; ~i; i = e[i].next){
43             int v = e[i].v;
44             if(dis[v] > dis[x] + e[i].cost){
45                 dis[v] = dis[x] + e[i].cost;
46                 if(inq[v] == 0){
47                     inq[v] = 1;
48                     cnt[v]++;
49                     if(cnt[v] > n + 1) //这里稍微写大点也没事
50                         return false;
51                     Q.push(v);
52                 }
53             }
54         }
55     }
56     return true;
57 }
58 
59 void Add_edge(int u,int v,int c){
60     e[++ecnt].next = first[u];
61     e[ecnt].v = v;
62     e[ecnt].cost = c;
63     first[u] = ecnt;
64 }
65 
66 int main(){
67     int a,b,c;
68     char s[10];
69     while(scanf("%d",&n) != EOF,n){
70         memset(first,-1,sizeof(first));
71         ecnt = 0;
72         scanf("%d",&m);
73         for(int i = 1; i <= m; ++i){
74             scanf("%d%d%s%d",&a,&b,s,&c);
75             if(s[0] == 'g') Add_edge(a + b,a - 1,-c - 1);
76             else    Add_edge(a - 1,a + b,c - 1);
77         }
78         for(int i = 0; i <= n; ++i) Add_edge(n + 1,i,0);
79         if(Spfa(n + 1)) printf("lamentable kingdom\n");
80         else printf("successful conspiracy\n");
81     }
82     return 0;
83 }
View Code

相关文章: