• 差分约束


    我的理解:

    给定一个变量如X0(类似于物理的参照物),求所有Xk-X0的最大值Dk。

    如:

    Xa-X0<=Dk,

    如果Xb-Xa<=L,则有

    Xb-X0<=Dk+L,

    对于Xb-Xa<=L,

    变形为Xa+L>=Xb,

    (Xa-X0)+L>=(Xb-X0)

    Da+L>=Db

    相当于点a到点b有一条长度为L的有向边,当Da+L>=b,点b的最短路修改为从起点到点a的最短路+点a到点b。

    求最短路后,相当于求出Xk-X0<=V中,V的最小值(其它V都无意义,Xk-X0<=V<=any V')。这就是Xk-X0的最大值(它不能取大于V的值,否则式子Xk-X0<=V不成立)。

    study from:

    https://blog.csdn.net/my_sunshine26/article/details/72849441

    https://blog.csdn.net/lyy289065406/article/details/6648679

     题目:

    1.

    http://poj.org/problem?id=1716

    study from:https://blog.csdn.net/lyy289065406/article/details/6648679

    贪心

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <time.h>
     6 #include <string>
     7 #include <set>
     8 #include <map>
     9 #include <list>
    10 #include <stack>
    11 #include <queue>
    12 #include <vector>
    13 #include <bitset>
    14 #include <algorithm>
    15 #include <iostream>
    16 using namespace std;
    17 #define ll long long
    18 #define minv 1e-6
    19 #define inf 1e9
    20 #define pi 3.1415926536
    21 #define nl 2.7182818284
    22 const ll mod=1e9+7;//998244353
    23 const int maxn=1e4+10;
    24 
    25 struct node
    26 {
    27     int a,b;
    28 }f[maxn];
    29 
    30 bool vis[maxn]={0};
    31 
    32 int cmp(node x,node y)
    33 {
    34     if (x.b==y.b)
    35         return x.a<y.a;
    36     else
    37         return x.b<y.b;
    38 }
    39 
    40 int main()
    41 {
    42     int n,i,sum=0,x,y;
    43     scanf("%d",&n);
    44     for (i=1;i<=n;i++)
    45         scanf("%d%d",&f[i].a,&f[i].b);
    46     sort(f+1,f+n+1,cmp);
    47     x=-1,y=-1;
    48     for (i=1;i<=n;i++)
    49     {
    50         if (y<f[i].a)
    51             y=f[i].b,sum++;
    52         if (x<f[i].a)
    53         {
    54             sum++;
    55             if (y!=f[i].b)
    56             {
    57                 x=y;
    58                 y=f[i].b;
    59             }
    60             else
    61                 x=f[i].b-1;
    62         }
    63     }
    64     cout<<sum;
    65     return 0;
    66 }

    sum[b]-sum[a-1]>=2
    sum[b]-2>=sum[a-1]
    b -> a-1    len=-2

    sum[x+1]+0>=sum[x]
    x+1 -> x    len=0

    sum[x]+1>=sum[x+1]
    x -> x+1    len=1

    第三个式子容易忘

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 #include <algorithm>
     15 #include <iostream>
     16 using namespace std;
     17 #define ll long long
     18 #define minv 1e-6
     19 #define inf 1e9
     20 #define pi 3.1415926536
     21 #define nl 2.7182818284
     22 const ll mod=1e9+7;//998244353
     23 const int maxn=1e4+10;
     24 
     25 /*
     26 sum[b]-sum[a-1]>=2
     27 sum[b]-2>=sum[a-1]
     28 b -> a-1    len=-2
     29 
     30 sum[x+1]+0>=sum[x]
     31 x+1 -> x    len=0
     32 
     33 sum[x]+1>=sum[x+1]
     34 x -> x+1    len=1
     35 */
     36 
     37 struct node
     38 {
     39     int d,len;
     40     node *next;
     41 }*prenode[10],*e[maxn];
     42 
     43 int preint[10],dist[maxn],q[maxn];
     44 bool vis[maxn]={0};
     45 
     46 int main()
     47 {
     48     node *p;
     49     int n,i,a,b,head,tail,d,dd,value=10000;
     50     scanf("%d",&n);
     51     for (i=1;i<=n;i++)
     52     {
     53         scanf("%d%d",&a,&b);
     54         p=(node*) malloc (sizeof(node));
     55         p->d=a-1;
     56         p->len=-2;
     57         p->next=e[b];
     58         e[b]=p;
     59     }
     60     for (i=0;i<=value;i++)
     61     {
     62         p=(node*) malloc (sizeof(node));
     63         p->d=i-1;
     64         p->len=0;
     65         p->next=e[i];
     66         e[i]=p;
     67     }
     68     for (i=-1;i<=value-1;i++)
     69     {
     70         p=(node*) malloc (sizeof(node));
     71         p->d=i+1;
     72         p->len=1;
     73         p->next=e[i];
     74         e[i]=p;
     75     }
     76     fill(dist-1,dist+value,inf);
     77     dist[value]=0;
     78     fill(vis-1,vis+value,0);
     79     vis[value]=1;
     80     head=0,tail=1;
     81     q[1]=value;
     82     while (head!=tail)
     83     {
     84         head=(head+1)%10001;
     85         d=q[head];
     86         p=e[d];
     87         while (p)
     88         {
     89             dd=p->d;
     90             if (dist[dd]>dist[d]+p->len)
     91             {
     92                 dist[dd]=dist[d]+p->len;
     93                 if (!vis[dd])
     94                 {
     95                     vis[dd]=1;
     96                     tail=(tail+1)%10001;
     97                     q[tail]=dd;
     98                 }
     99             }
    100             p=p->next;
    101         }
    102         vis[d]=0;
    103     }
    104     printf("%d",-dist[-1]);
    105     return 0;
    106 }

    2.

    http://poj.org/problem?id=1201

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 #include <algorithm>
     15 #include <iostream>
     16 using namespace std;
     17 #define ll long long
     18 #define minv 1e-6
     19 #define inf 1e9
     20 #define pi 3.1415926536
     21 #define nl 2.7182818284
     22 const ll mod=1e9+7;//998244353
     23 const int maxn=5e4+10;
     24 
     25 /*
     26 sum[b]-sum[a-1]>=2
     27 sum[b]-2>=sum[a-1]
     28 b -> a-1    len=-2
     29 
     30 sum[x+1]+0>=sum[x]
     31 x+1 -> x    len=0
     32 
     33 sum[x]+1>=sum[x+1]
     34 x -> x+1    len=1
     35 */
     36 
     37 struct node
     38 {
     39     int d,len;
     40     node *next;
     41 }*prenode[10],*e[maxn];
     42 
     43 int preint[10],dist[maxn],q[maxn];
     44 bool vis[maxn]={0};
     45 
     46 int main()
     47 {
     48     node *p;
     49     int n,i,a,b,c,head,tail,d,dd,value=50000;
     50     scanf("%d",&n);
     51     for (i=1;i<=n;i++)
     52     {
     53         scanf("%d%d%d",&a,&b,&c);
     54         p=(node*) malloc (sizeof(node));
     55         p->d=a-1;
     56         p->len=-c;
     57         p->next=e[b];
     58         e[b]=p;
     59     }
     60     for (i=0;i<=value;i++)
     61     {
     62         p=(node*) malloc (sizeof(node));
     63         p->d=i-1;
     64         p->len=0;
     65         p->next=e[i];
     66         e[i]=p;
     67     }
     68     for (i=-1;i<=value-1;i++)
     69     {
     70         p=(node*) malloc (sizeof(node));
     71         p->d=i+1;
     72         p->len=1;
     73         p->next=e[i];
     74         e[i]=p;
     75     }
     76     fill(dist-1,dist+value,inf);
     77     dist[value]=0;
     78     fill(vis-1,vis+value,0);
     79     vis[value]=1;
     80 
     81     head=0,tail=1;
     82     q[1]=value;
     83     while (head!=tail)
     84     {
     85         head=(head+1)%50001;
     86         d=q[head];
     87         p=e[d];
     88         while (p)
     89         {
     90             dd=p->d;
     91             if (dist[dd]>dist[d]+p->len)
     92             {
     93                 dist[dd]=dist[d]+p->len;
     94                 if (!vis[dd])
     95                 {
     96                     vis[dd]=1;
     97                     tail=(tail+1)%50001;
     98                     q[tail]=dd;
     99                 }
    100             }
    101             p=p->next;
    102         }
    103         vis[d]=0;
    104     }
    105     printf("%d",-dist[-1]);
    106     return 0;
    107 }

    3.

    http://poj.org/problem?id=3169

    BellmanFord

    在这里,神奇地速度竟然比SPFA快

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 //#include <ext/rope>
     15 #include <algorithm>
     16 #include <iostream>
     17 using namespace std;
     18 #define ll long long
     19 #define minv 1e-6
     20 #define inf 2e9
     21 #define pi 3.1415926536
     22 #define nl 2.7182818284
     23 const ll mod=1e9+7;//998244353
     24 const int maxn=1e4+10;
     25 
     26 /**
     27 a[y]-a[x]<=z
     28 a[x]+z>=a[y]
     29 x->y z
     30 
     31 a[y]-a[x]>=z
     32 a[y]-z>=a[x]
     33 y->x -z
     34 
     35 a[x+1]-a[x]>=0
     36 a[x+1]>=a[x]
     37 x+1->x 0
     38 **/
     39 
     40 struct rec
     41 {
     42     int x,y,z;
     43 }f[30000];///ml+md+n
     44 
     45 int dist[maxn],g=0;
     46 
     47 bool bell()
     48 {
     49     bool vis=0;
     50     int i;
     51     for (i=1;i<=g;i++)
     52         if (dist[f[i].y]>dist[f[i].x]+f[i].z)   ///don't need to judge ==inf !=inf
     53         {
     54             dist[f[i].y]=dist[f[i].x]+f[i].z;
     55             vis=1;
     56         }
     57     return vis;
     58 }
     59 
     60 int main()
     61 {
     62     int n,ml,md,i,x,y,z;
     63     scanf("%d%d%d",&n,&ml,&md);
     64     for (i=1;i<=ml;i++)
     65     {
     66         scanf("%d%d%d",&x,&y,&z);
     67         f[++g]={x,y,z};
     68     }
     69     for (i=1;i<=md;i++)
     70     {
     71         scanf("%d%d%d",&x,&y,&z);
     72         f[++g]={y,x,-z};
     73     }
     74 
     75     for (i=1;i<n;i++)
     76         f[++g]={i+1,i,0};
     77 
     78     fill(dist,dist+n+1,inf);
     79     dist[1]=0;
     80     for (i=1;i<=n;i++)
     81         if (!bell())
     82             break;
     83     if (i==n+1)
     84         printf("-1");
     85     else if (dist[n]==inf)
     86         printf("-2");
     87     else
     88         printf("%d",dist[n]);
     89     return 0;
     90 }
     91 /*
     92 4 2 0
     93 1 2 10
     94 3 4 20
     95 
     96 4 1 1
     97 1 2 8
     98 1 2 12
     99 
    100 3 1 1
    101 1 3 10
    102 2 3 12
    103 
    104 4 1 1
    105 2 3 8
    106 2 3 12
    107 */

    SPFA

    有些样例不对,因为如果使用SPFA,有些点不能到达,但代码通过了这题

    如:

    4 1 1
    2 3 8
    2 3 12
    wrong!

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 #include <ext/rope>
     15 #include <algorithm>
     16 #include <iostream>
     17 using namespace std;
     18 #define ll long long
     19 #define minv 1e-6
     20 #define inf 2e9
     21 #define pi 3.1415926536
     22 #define nl 2.7182818284
     23 const ll mod=1e9+7;//998244353
     24 const int maxn=1e3+10;
     25 
     26 /**
     27 a[y]-a[x]<=z
     28 a[x]+z>=a[y]
     29 x->y z
     30 
     31 a[y]-a[x]>=z
     32 a[y]-z>=a[x]
     33 y->x -z
     34 
     35 a[x+1]-a[x]>=0
     36 a[x+1]>=a[x]
     37 x+1->x 0
     38 **/
     39 
     40 struct node
     41 {
     42     int d,len;
     43     node *next;
     44 }*e[maxn];
     45 
     46 int dist[maxn],q[maxn],use[maxn];
     47 bool vis[maxn];
     48 
     49 int main()
     50 {
     51     node *p;
     52     int n,ml,md,i,x,y,z,d,dd,head,tail;
     53     scanf("%d%d%d",&n,&ml,&md);
     54     for (i=1;i<=ml;i++)
     55     {
     56         scanf("%d%d%d",&x,&y,&z);
     57         p=(node*) malloc (sizeof(node));
     58         p->d=y;
     59         p->len=z;
     60         p->next=e[x];
     61         e[x]=p;
     62     }
     63     for (i=1;i<=md;i++)
     64     {
     65         scanf("%d%d%d",&x,&y,&z);
     66         p=(node*) malloc (sizeof(node));
     67         p->d=x;
     68         p->len=-z;
     69         p->next=e[y];
     70         e[y]=p;
     71     }
     72     for (i=1;i<n;i++)
     73     {
     74         p=(node*) malloc (sizeof(node));
     75         p->d=i;
     76         p->len=0;
     77         p->next=e[i+1];
     78         e[i+1]=p;
     79     }
     80 
     81     fill(dist,dist+n+1,inf);
     82     dist[1]=0;
     83     memset(vis,0,sizeof(vis));
     84     vis[1]=1;
     85     memset(use,0,sizeof(use));
     86     q[1]=1;
     87     head=0;
     88     tail=1;
     89     while (head!=tail)
     90     {
     91         head=(head+1)%n;
     92         d=q[head];
     93         p=e[d];
     94         while (p)
     95         {
     96             dd=p->d;
     97             if (dist[dd]>dist[d]+p->len)
     98             {
     99                 dist[dd]=dist[d]+p->len;
    100                 use[dd]++;
    101                 if (use[dd]>=n)
    102                 {
    103                     printf("-1");
    104                     return 0;
    105                 }
    106                 if (!vis[dd])
    107                 {
    108                     vis[dd]=1;
    109                     tail=(tail+1)%n;
    110                     q[tail]=dd;
    111                 }
    112             }
    113             p=p->next;
    114         }
    115         vis[d]=0;
    116     }
    117     if (dist[n]==inf)
    118         printf("-2");
    119     else
    120         printf("%d",dist[n]);
    121     return 0;
    122 }
    123 /*
    124 4 2 0
    125 1 2 10
    126 3 4 20
    127 
    128 4 1 1
    129 1 2 8
    130 1 2 12
    131 
    132 3 1 1
    133 1 3 10
    134 2 3 12
    135 
    136 4 1 1
    137 2 3 8
    138 2 3 12
    139 wrong!
    140 */
  • 相关阅读:
    CRM4.0多组织安装和设置
    如何找回你的VirtualPC2007控制台
    线性表
    时间复杂度
    栈与队列
    字符串排序问题
    浙江企业网喜讯之一
    初次体验到C#范型的魅力
    ajax 或 js 异步判断用户名是否存在
    html基础知识1(基本标签)20170307
  • 原文地址:https://www.cnblogs.com/cmyg/p/9557681.html
Copyright © 2020-2023  润新知