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
");
60         else
61             printf("lamentable kingdom
");
62     }
63     return 0;
64 }
View Code
原文地址:https://www.cnblogs.com/lahblogs/p/3439869.html