King(差分约束)
http://poj.org/problem?id=1364
题意:输入i,n,gt(lt),k; 判断是否存在这样一个序列,从第 i 项加到第 n+i 项的和 <(lt) k 或 >(gt) k.
思路: 由题意知
gt: Sn+i - Si > k;.......(1)
lt: Si - Sn+i < k;........(2)
由(1)(2)得 :
gt: Si - Sn+i <= -k-1;
lt: Si - Sn+i <= k-1;
根据<n+i,i,-k-1> <n+i,i,k-1>建图。
1 #include <stdio.h> 2 #include <string.h> 3 const int N=120; 4 const int INF=1<<28; 5 struct node 6 { 7 int u,v,w; 8 } edge[N]; 9 int cnt,n,m; 10 int dis[N]; 11 void add(int u,int v,int w) 12 { 13 edge[cnt].u = u; 14 edge[cnt].v = v; 15 edge[cnt++].w = w; 16 17 } 18 int bellman_ford( ) 19 { 20 for (int i = 0; i <= n; i++) 21 dis[i] = 0;//将源点到各点的距离初始化为零, 22 //因为根据不等式知源点到各点的最短距离肯定小于零 23 for (int i = 0; i < n; i ++) 24 { 25 for (int j = 0; j < cnt; j ++) 26 { 27 int u = edge[j].u; 28 int v = edge[j].v; 29 if (dis[v] > dis[u]+edge[j].w)//更新各点到源点的距离 30 dis[v] = dis[u]+edge[j].w; 31 } 32 } 33 for (int j = 0 ; j < cnt; j ++)//判断负环 34 { 35 int u = edge[j].u; 36 int v = edge[j].v; 37 if (dis[v] > dis[u]+edge[j].w) 38 return false; 39 } 40 return true; 41 } 42 int main() 43 { 44 char s[3]; 45 int u,v,w; 46 while(~scanf("%d",&n)&&n) 47 { 48 cnt = 0; 49 scanf("%d",&m); 50 for (int i = 0; i < m; i++) 51 { 52 scanf("%d %d %s %d",&u,&v,s,&w); 53 if (s[0]=='g') 54 add(u+v,u-1,-w-1); 55 else 56 add(u-1,u+v,w-1); 57 } 58 if (!bellman_ford()) 59 printf("successful conspiracy\n"); 60 else 61 printf("lamentable kingdom\n"); 62 } 63 return 0; 64 }