zoukankan      html  css  js  c++  java
  • 差分约束系统

    有不等式
    x1-x2<=0;
    x1-x2<=-1;
    x2-x5<=1;
    x3-x1<=5;
    x4-x1<=4;
    x4-x3<=-1;
    x5-x3<=-3;
    x5-x4<=-3;
    在每个不等式都是两个未知数的差小于等于某个常数(或大于等于),这样的不等式组就称为差分约束系统;
    这个不等式组要么无解,要么有无穷多的解;
    差分约束系统求解要利用最短路径的三角不等式:d(v)<=d(u)+edge[u][v];d(u),d(v)表示源点到u,v点的最短路径长度;
    构造方法:
    (1)每个不等式中的每个未知数xi对应图中的一个顶点vi;
    (2)把所有的不等式化成图中的一条边。对于不等式xi-xj<=c,把他化成三角不等式:xi<=xj+c,就有边<vj,vi>的权值等于c(edge[vj[vi]=c);
    设一个起点,最后在这张图上求一次单源最短路径即可。用Bellman-ford算法比较好,方程组无解时也就是存在负环;起点到各点的最短路径即为该不等式组的一组解;

     1 //poj3169
     2 /*
     3 网上很多代码都是错的,但是竟然都过了,
     4 所以差不多网上代码出于同一人之手(^v^)
     5 */
     6 #include<stdio.h>
     7 #include<string.h>
     8 #define INF 99999999
     9 struct node
    10 {
    11     int u;
    12     int v;
    13     int w;
    14 }edge[22003];
    15 int index,n,ml,md,dis[1003];
    16 void add(int x,int y,int z)
    17 {
    18     int i,j;
    19     edge[index].u=x;
    20     edge[index].v=y;
    21     edge[index].w=z;
    22     index++;
    23 }
    24 int bell()
    25 {
    26     int i,j;
    27     for(i=1;i<=n;i++)
    28         dis[i]=INF;
    29     dis[1]=0;
    30     for(i=1;i<n;i++)
    31     {
    32         for(j=1;j<index;j++)
    33         {
    34             int u=edge[j].u;
    35             int v=edge[j].v;
    36             int w=edge[j].w;
    37             if(dis[v]>dis[u]+w)
    38             {
    39                 dis[v]=dis[u]+w;
    40             }
    41         }
    42     }
    43     for(i=1;i<index;i++)
    44     {
    45         int u=edge[i].u;
    46         int v=edge[i].v;
    47         int w=edge[i].w;
    48         if(dis[v]>dis[u]+w&&dis[u]!=INF)
    49             return 0;
    50     }
    51     return 1;
    52 }
    53 int main()
    54 {
    55     int i,j;
    56     while(scanf("%d%d%d",&n,&ml,&md)!=EOF)
    57     {
    58         index=1;
    59         int x,y,z;
    60         for(i=1;i<n;i++)
    61         {
    62             add(i+1,i,0);
    63         }
    64         for(i=1;i<=ml;i++)
    65         {
    66             scanf("%d%d%d",&x,&y,&z);
    67             add(x,y,z);
    68         }
    69         for(i=1;i<=md;i++)
    70         {
    71             scanf("%d%d%d",&x,&y,&z);
    72             add(y,x,-z);
    73         }
    74         int ans=bell();
    75         if(ans==0)
    76             printf("-1
    ");
    77         else if(dis[n]==INF)
    78         {
    79             printf("-2
    ");
    80         }
    81         else printf("%d
    ",dis[n]);
    82 
    83     }
    84 }
  • 相关阅读:
    hdu 3722 Card Game 二分图的最大权匹配
    如何将中国知网CNKI中的文献导入EndNote X6
    高性能以太网芯片W5500 数据手册 V1.0(二)
    (贪心5.1.2)POJ 2287 Tian Ji -- The Horse Racing
    [置顶] 斗地主算法的设计与实现--项目介绍&如何定义和构造一张牌
    Robotium学习笔记一
    Robotium学习笔记二
    Robotium学习笔记三
    做一个测试经理我还差多少?
    [每日一题] 11gOCP 1z0-053 :2013-10-9 backup with the KEEP option....................................33
  • 原文地址:https://www.cnblogs.com/sweat123/p/4507405.html
Copyright © 2011-2022 走看看