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 }