zoj2770 Burn the Linked Camp --- 差分约束

有n个营地,每个营地至多容纳Ci人,给出m个条件:第i到第j个营地之间至少有k人。

问n个营地总共至少有多少人。

此题显然差分约束,要求最小值,则建立x-y>=z方程组,建图求最长路。

用d[i]表示[1,i]个帐篷中一共多少人,根据题意可得到不等关系:

1、0<=d[i]-d[i-1]<=C[i]

2、d[j]-d[i]>=k

此外,我们添加0为附加结点,则0到其他点也要建边。

再求解0为源点的最长路即可。

我的坑点是,判负环返回0,否则返回d[n]。

而d[n]本身就可能是0。这里要注意下

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define eps 1e-6
#define ll __int64
#define maxm 20010
#define maxn 1010
using namespace std;

struct node
{
    int v,w,next;
}e[maxm];

int head[maxn],d[maxn],inq[maxn],outq[maxn],n,m,h;

void init()
{
    memset(head,-1,sizeof head);
    h=0;
}

void addedge(int a,int b,int c)
{
    e[h].v=b;
    e[h].w=c;
    e[h].next=head[a];
    head[a]=h++;
}

int spfa(int st)
{
    memset(inq,0,sizeof inq);
    memset(outq,0,sizeof outq);
    for(int i=0;i<=n;i++)
        d[i]=-0xFFFFFF;
    d[st]=0;
    inq[st]=1;
    queue<int> q;
    q.push(st);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        inq[x]=0;
        outq[x]++;
        if(outq[x]>n) return 0;//存在负环
        for(int i=head[x];i!=-1;i=e[i].next)
        {
            if(d[e[i].v]<d[x]+e[i].w)
            {
                d[e[i].v]=d[x]+e[i].w;
                if(!inq[e[i].v])
                {
                    inq[e[i].v]=1;
                    q.push(e[i].v);
                }
            }
        }
    }
    return 1;
}

int main()
{
    int a,b,c;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&c);
            addedge(i-1,i,0);
            addedge(i,i-1,-c);
            addedge(0,i,0);//所有边与附加结点0相连
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addedge(a-1,b,c);
        }
        int ans=spfa(0);
       // for(int i=0;i<=n;i++)
       //     printf("%d ",d[i]);
       // puts("");
        if(ans==0)
            printf("Bad Estimations\n");
        else printf("%d\n",d[n]);
    }
    return 0;
}

zoj2770 Burn the Linked Camp --- 差分约束,布布扣,bubuko.com

时间: 2024-10-11 10:23:04

zoj2770 Burn the Linked Camp --- 差分约束的相关文章

ZOJ 2770 Burn the Linked Camp 差分约束+SPFA

第一道正儿八经的差分约束题 有排成一列的n个点,首先告诉你每个点的值最多是多少(最少显然要大于0),然后告诉你m段i,j,k,表示第i个点到第j个点的值的和至少有k,问你总和至少为多少. 要注意的是,告诉你的所有关系式都不要忘记建边,一开始漏了大于0的条件调半天o(╯□╰)o 不等式的形式是a-b<=c这样的= = 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <

ZOJ 2770 Burn the Linked Camp 差分约束

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2770 Burn the Linked Camp Time Limit: 2 Seconds      Memory Limit: 65536 KB It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeate

ZOJ 2770 Burn the Linked Camp 差分约束 (转)

It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Bei's wrong decision that he divided his large troops into a number of ca

ZOJ2770 Burn the Linked Camp(差分约束系统)

区间和一定要联系到前缀和. 这题,把前缀和看作点,从s0到sn: 对于每一个营地i的容量capi,有这么个关系si-si-1<=capi: 对于每一个区间的评估i,j,k,有sj-si-1>=k,即si-1-sj<=k: 接下来就是连边了,对于v<=u+w由u向v连权w的边,超级源向n+1个点连权0的边. 最后跑SPFA,如果出现负环则无解:而有解的话,所求答案就在d[sn]里,不过因为题目的前缀和是非负整数且要求的最少,所以就要让d中所有数都同时加上合适的数得到另一个真正所求的解

Burn the Linked Camp(bellman 差分约束系统)

Burn the Linked Camp Time Limit: 2 Seconds      Memory Limit: 65536 KB It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Be

ZOJ 2770 Burn the Linked Camp( 差分约束啊 )

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1770 It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Bei'

zoj 2770 Burn the Linked Camp

今天刚刚学差分约束系统.利用最短路求解不等式.世界真的好奇妙!感觉不等式漏下几个会导致WA!! #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; const int maxn = 1111; vector<int>ljb[ma

差分约束小结

ZOJ 2770 Burn the Linked Camp /* ZOJ 2770 Burn the Linked Camp 差分约束 */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int MAXN = 1009; struct Edge { int v, ne, c; } G[MAXN*MAXN]

差分约束-zoj-2770

Burn the Linked Camp It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Bei's wrong decision that he divided his large troop