• ZOJ 2770火烧连营——差分约束


    偶尔做了一下差分约束。

    题目大意:给出n个军营,每个军营最多有ci个士兵,且[ai,bi]之间至少有ki个士兵,问最少有多少士兵。

    ————————————————————————————————————————————————---

    差分约束:就是利用多个不等式来推导另一个不等式。

    由于不等式a-b<=c和求最短路径时的三角形不等式相同,就变成了求最短路。

    所有不等式化为a-b<=c的形式,则建造b到a的边,权为c。

    求a到b的最短距离,则转化为b-a<=c,距离的值为c。

    该题中:

    Si表示从第一营到i营的人数,则有:

    每个营的人数不少于0,Si-Si-1>=0,进而推出Si-1-Si<=0;

    每个营的人数不大于Ci,从而推出Si-Si-1<=Ci;

    第i营到第j营人数不少于k,从而推出Sj-Si-1>=k,进而推出Si-1-Sj<=-k

    从以上三组不等式分别建边,组成图。

    求的是所有应最少有多少人,即Sn-S0>=x,求的就是x.

    从上式推出S0-Sn<=-x,所以从Sn求到S0的最短路,就是x的相反数。

    ————————————————————————————————————————————————————

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<queue>
     7 using namespace std;
     8 int n,m;
     9 struct edge
    10 {
    11     int u,v,w,next;
    12 }e[20010];
    13 int head[1010],js;
    14 int dis[1010];
    15 int inqt[1010];
    16 bool inq[1010];
    17 queue<int>q;
    18 void init()
    19 {
    20     memset(head,0,sizeof(head));
    21     js=0;
    22 }
    23 void readint(int &x)
    24 {
    25     char c=getchar();
    26     int f=1;
    27     for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-f;
    28     x=0;
    29     for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
    30     x*=f;
    31 }
    32 void addage(int u,int v,int w)
    33 {
    34     e[++js].u=u;e[js].v=v;e[js].w=w;
    35     e[js].next=head[u];head[u]=js;
    36 }
    37 bool spfa()
    38 {
    39     memset(dis,0x7f,sizeof(dis));
    40     memset(inq,0,sizeof(inq));
    41     memset(inqt,0,sizeof(inqt));
    42     dis[n]=0;
    43     inqt[n]=1;
    44     q.push(n);
    45     inq[n]=1;
    46     while(!q.empty())
    47     {
    48         int u=q.front();
    49         q.pop();
    50         inq[u]=0;
    51         for(int i=head[u];i;i=e[i].next)
    52         {
    53             int v=e[i].v;
    54             if(dis[v]>dis[u]+e[i].w)
    55             {
    56                 dis[v]=dis[u]+e[i].w;
    57                 if(!inq[v])
    58                 {
    59                     q.push(v);
    60                     inq[v]=1;
    61                     inqt[v]++;
    62                     if(inqt[v]>n)return 0;
    63                 }
    64             }
    65         }
    66     }
    67     return 1;
    68 }
    69 int main()
    70 {
    71     while(scanf("%d%d",&n,&m)==2)
    72     {
    73         init();
    74         for(int c,i=1;i<=n;i++)
    75         {
    76             readint(c);
    77             addage(i-1,i,c);
    78             addage(i,i-1,0);
    79         }
    80         for(int a,b,c,i=0;i<m;i++)
    81         {
    82             readint(a);readint(b);readint(c);
    83             addage(b,a-1,-c);
    84         }
    85         if(spfa())printf("%d\n",-dis[0]);
    86         else printf("Bad Estimations\n");
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    数据挖掘相关资料收集(持续更新)
    常见面试之机器学习算法思想简单梳理
    在c中保存状态
    lua 和 c
    lua 基础库
    lua 面向对象
    lua 高级
    lua 基础
    lua中的协程
    cocos2d中的可见性检测
  • 原文地址:https://www.cnblogs.com/gryzy/p/6211282.html
Copyright © 2020-2023  润新知