• 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 }


  • 相关阅读:
    POJ 2195 Going Home (费用流)
    POJ 1087 A Plug for UNIX (网络流,最大流)
    凸包的直径——旋转卡壳
    凸包--Graham扫描法
    POJ 3167 Layout(差分约束)
    POJ 2187 Beauty Contest(凸包,旋转卡壳)
    HDU 1392 Surround the Trees(凸包)
    HDU 3416 Marriage Match IV(最短路,网络流)
    【USACO4.2】草地排水Drainage Ditches(最大流)
    【模板】网络最大流
  • 原文地址:https://www.cnblogs.com/pony1993/p/2667078.html
Copyright © 2020-2023  润新知