POJ 3169 Layout(差分约束系统)

这道题是经典的差分约束系统,这道题可以看到明确的其源点1,所以求解的是从1出发终点为n的最短路。 

差分约束系统有两种方式可求解,最短路和最长路。当我们把不等式整理成d[a]+w<=d[b]时,我们求最长路。

整理成d[a]+w>=d[b]时,我们求最短路。

当求最短路时,我们通常要把各点距离初始化为正无穷,求最短路,把各点距离逐渐减小,直到符合所有不等式。 

代码:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <queue>
 6  using  namespace std;
 7  const  int maxn= 10010;
 8  const  int inf= 0x7fffffff;
 9  struct node
10 {
11      int v;
12      int u;
13      int next;
14 }edge[maxn<< 1];
15  int head[maxn],dist[maxn],cnt[maxn],vis[maxn];
16  int p,n,ml,md,max;
17 queue < int> q;
18  void add( int a, int b, int c)
19 {
20     edge[p].v=b;
21     edge[p].u=c;
22     edge[p].next=head[a];
23     head[a]=p;
24     p++;
25 }
26  int spfa()
27 {
28      int k;
29     dist[ 1]= 0;
30     vis[ 1]= 1;
31     q.push( 1);
32     cnt[ 1]++;
33      while(!q.empty())
34     {
35         k=q.front();
36         q.pop();
37         vis[k]= 0;
38          for(p=head[k];p!=- 1;p=edge[p].next)
39         {
40              if(dist[edge[p].v]>dist[k]+edge[p].u)
41             {
42                 dist[edge[p].v]=dist[k]+edge[p].u;
43                  if(!vis[edge[p].v])
44                 {
45                      if(++cnt[edge[p].v]>n)
46                          return  0;
47                     vis[edge[p].v]= 1;
48                     q.push(edge[p].v);
49                 }
50             }
51         }
52     }
53      return  1;
54 }
55  void init()
56 {
57      int i;
58      for(i= 1;i<=n;i++)
59         dist[i]=inf;
60     memset(head,- 1, sizeof(head));
61     memset(vis, 0, sizeof(vis));
62 }
63  int main()
64 {
65      int i,a,b,c;
66      while(~scanf( " %d%d%d ",&n,&ml,&md))
67     {
68         init();
69         p= 0;
70          for(i= 0;i<ml;i++)
71         {
72             scanf( " %d%d%d ",&a,&b,&c);
73             add(a,b,c);
74         }
75          for(i= 0;i<md;i++)
76         {
77             scanf( " %d%d%d ",&a,&b,&c);
78             add(b,a,-c);
79         }
80          for(i= 1;i<n;i++)
81             add(i+ 1,i, 0);
82          if(!spfa())
83             puts( " -1 ");
84          else  if(dist[n]-dist[ 0]>=inf)
85             puts( " -2 ");
86          else
87             printf( " %d\n ",dist[n]-dist[ 0]);
88     }
89      return  0;
90 }


你可能感兴趣的:(layout)