zoj2770Burn the Linked Camp(差分约束)

来源:互联网 发布:ios 原生同步网络请求 编辑:程序博客网 时间:2024/05/22 14:14

题目请戳这里

题目大意:刘备有n个军营,陆逊要烧之,所以要事先估计刘备有多少人。已知刘备第i个军营不超过ci个人,通过侦查,陆逊有m个消息,表示刘备第i个军营到第j个军营至少有k人,现在要估计刘备军队至少多少人。

题目分析:差分约束。根据题意可以整理出一些不等式组:

1。首先每个军营的人数0<=ai<=ci,用si表示前i个军营人数总和。那么就有si - si-1 >= 0即si-1 - si <= 0,以及si - si-1 <= ci

2。第i个军营到第j个军营至少k人,sj - si-1 >= k,即si-1 - sj <= -k

3。第i个军营到第j个军营人数不能超过sigma(ci~cj),即sj - si-1 <= sigma(ci~cj)

这样差分约束系统就建立好了。再看要求什么。

题目要求估计刘备军队人数,即sn-s0,那么以n为原点求最短路,就能满足上面的约束关系,那么答案就是n到0的距离取反,即-s[0]。

详情请见代码:

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N = 1005;const int M = 10005;const int INF = 0x3f3f3f3f;int n,m;int c[N];int head[N];struct node{    int to,val,next;}g[M<<2];int num;bool ok;bool flag[N];int dis[N];int queue[N];int in[N];int front,rear;void build(int s,int e,int v){    g[num].to = e;    g[num].val = v;    g[num].next = head[s];    head[s] = num++;}void SPFA(){    int i,j;    for(i = 0;i <= n;i ++)    {        flag[i] = false;        dis[i] = INF;        in[i] = 0;    }    dis[n] = 0;    flag[n] = true;    in[n] ++;    front = rear = 0;    queue[rear ++] = n;    while(front < rear)    {        int u = queue[front ++];        flag[u] = false;        for(i = head[u];i != -1;i = g[i].next)        {            if(dis[g[i].to] > dis[u] + g[i].val)            {                dis[g[i].to] = dis[u] + g[i].val;                if(flag[g[i].to] == false)                {                    if(in[g[i].to] == n - 1)                    {                        ok = true;                        return;                    }                    in[g[i].to] ++;                    flag[g[i].to] = true;                    queue[rear ++] = g[i].to;                }            }        }    }}int main(){    int i,j,k;    while(scanf("%d%d",&n,&m) != EOF)    {        num = 0;        memset(head,-1,sizeof(head));        c[0] = 0;        for(i = 1;i <= n;i ++)        {            scanf("%d",&c[i]);            build(i - 1,i,c[i]);            c[i] += c[i - 1];            build(i,i - 1,0);        }        while(m --)        {            scanf("%d%d%d",&i,&j,&k);            build(i - 1,j,c[j] - c[i - 1]);            build(j,i - 1,-k);        }        ok = false;        SPFA();        if(ok)            puts("Bad Estimations");        else            printf("%d\n",dis[n] - dis[0]);    }    return 0;}//50ms676k


原创粉丝点击