前言

我对差分约束有我个人独特的看法,写这题解既是与大家分享,又算作我对差分约束系统的总结。

浅谈差分约束

对于一些给出形如\(x_i-x_j\leq a\)不等式(差分约束)组,求\(x_t-x_s\)的最大值问题,我们考虑把这些式子移项,变成\(x_i\leq x_j+a\)的形式。我们知道该问题存在解则所有的不等式都应该得到满足。而所有的\(x_i\leq x_j+a\)都得到满足的要求正好与最短路算法中最终结果算出来后的性质\(dis_i\leq dis_j+w_{i,j}\)类似,所以联想到可以用最短路来求解该方程组问题,即把\(\{x_n\}\)当做\(V\),对每个不等式建边\((j,i,a)\),设\(x_s=0\),跑最短路后,\(x_t\)即为最大值(因为xs=0了)。下证方法的正确性,先假设问题有解。

  1. 必要性 算出最短路后根据最短路的性质那么所有的不等式都应该被满足,说明答案是正确的。
  2. 充分性 根据最短路算法的过程\(x_i\)都被它的限制牢牢控制住,且有一个最严格的限制使得\(x_i\)恰好满足它,那么不可能存在比最短路结果更优的解,说明答案是最优的。

综上,算法正确。(谁看出了问题请联系我。)

无解的情况为图中有负环,对应到原问题中就是一个数比它自己大(小)。

分析此题

每个要求就是个差分约束,然后移项令路权为正,发现都是形如\(b\geq a+1\)的形式,与最长路的结果性质类似,故建立最长路模型,用Bellman-Ford(或者LPFA)求解。对小朋友的要求建模:

  1. a比b多:\(a>b \rightarrow a\geq b+1\)
  2. a不少于b:\(a \geq b \rightarrow a \geq b+0\)
  3. a跟b一样:\(a = b \rightarrow a \geq b+0 \& b \geq a+0\)

其余的都是对偶情况。考虑\(x_i>0 \rightarrow x_i\geq x_0+1\)用0节点向1-n连权为1的边,表示每个小朋友都要分到糖,将dis[0]设为0,这样对0节点的差分就是每个小朋友应得的点数。

然后注意无解的情况,最长路无解即有正环。另外输入的时候特判一下约束是否是“a大于a自己”这种类型的,直接输出-1,可以提高程序效率。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#define rg register
#pragma GCC optimize ("O0")
using namespace std;
typedef long long ll;
const int INF=0x7fffffff;
template<class T> inline T read(T&x){
    T data=0;
    int w=1;
    char ch=getchar();
    while(ch!='-'&&!isdigit(ch))
        ch=getchar();
    if(ch=='-')
        w=-1,ch=getchar();
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}

const int MAXN=1e5+7;
int n,m;

struct Edge
{
    int to,nx,w;
}E[MAXN*3]; // 0连边还要O(n)空间
int head[MAXN],ecnt;

inline void addedge(int x,int y,int w)
{
    E[++ecnt].to=y,E[ecnt].w=w;
    E[ecnt].nx=head[x],head[x]=ecnt;
}

int num[MAXN],dis[MAXN];
bool inq[MAXN];
queue<int>Q;

inline bool SPFA()
{
    memset(dis,-1,sizeof(dis));
    dis[0]=0;
    Q.push(0);
    inq[0]=1;
    num[0]=1;
    while(!Q.empty())
    {
        int x=Q.front();
        Q.pop();
        inq[x]=0;
        for(rg int i=head[x];i;i=E[i].nx)
        {
            int y=E[i].to;
            if(dis[y]<dis[x]+E[i].w)
            {
                dis[y]=dis[x]+E[i].w;
                if(!inq[y])
                {
                    if(++num[y]>=n) // 一个点最多被松弛n-1次,入队n-1次
                        return 0;
                    Q.push(y);
                    inq[y]=1;
                }
            }
        }
    }
    return 1;
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);read(m);
    for(rg int i=1;i<=m;++i)
    {
        int x,a,b;
        read(x);read(a);read(b);
        if(x==1)
        {
            addedge(a,b,0);
            addedge(b,a,0);
        }
        else if(x==2)
        {
            if(a==b)
            {
                printf("-1");
                return 0;
            }
            addedge(a,b,1);
        }
        else if(x==3)
        {
            addedge(b,a,0);
        }
        else if(x==4)
        {
            if(a==b)
            {
                printf("-1");
                return 0;
            }
            addedge(b,a,1);
        }
        else if(x==5)
        {
            addedge(a,b,0);
        }
    }
    for(rg int i=n;i>=1;--i)
        addedge(0,i,1);
//  cerr<<"build end"<<endl;
    if(!SPFA())
        printf("-1");
    else
    {
        ll ans=0;
        for(rg int i=1;i<=n;++i)
            ans+=dis[i];
        printf("%lld",ans);
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

Hint

ans要开long long,0节点向1-n连边要逆序,因为根据讨论

这个题原数据有一个点是一个十万的链

可以卡掉SPFA。

LG3275 【[SCOI2011]糖果】的更多相关文章

  1. bzoj2330: [SCOI2011]糖果

    2330: [SCOI2011]糖果 Time Limit: 10 Sec Memory Limit: 128 MB Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友 ...

  2. BZOJ 2330: [SCOI2011]糖果 [差分约束系统] 【学习笔记】

    2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5395  Solved: 1750[Submit][Status ...

  3. bzoj 2330 [SCOI2011]糖果(差分约束系统)

    2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3574  Solved: 1077[Submit][Status ...

  4. BZOJ 2330: [SCOI2011]糖果( 差分约束 )

    坑爹...要求最小值要转成最长路来做.... 小于关系要转化一下 , A < B -> A <= B - 1 ------------------------------------ ...

  5. [luogu P3275] [SCOI2011]糖果

    [luogu P3275] [SCOI2011]糖果 题目描述 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些 ...

  6. P3275 [SCOI2011]糖果 && 差分约束(二)

    学习完了差分约束是否有解, 现在我们学习求解最大解和最小解 首先我们回想一下是否有解的求解过程, 不难发现最后跑出来任意两点的最短路关系即为这两元素的最短路关系. 即: 最后的最短路蕴含了所有元素之间 ...

  7. [Luogu 3275] SCOI2011 糖果

    [Luogu 3275] SCOI2011 糖果 第一道差分约束.感谢 AZe. 我的理解是根据一些不等关系建一个图,在图上边跑一个最长路(有时候是最短路). 因为可能存在负环,所以必须用 SPFA! ...

  8. BZOJ 2330 SCOI2011糖果 差分约束

    2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2819  Solved: 820 题目连接 http://www ...

  9. BZOJ2330 SCOI2011 糖果 【差分约束】

    BZOJ2330 SCOI2011 糖果 Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一 ...

  10. 【bzoj2330】: [SCOI2011]糖果 图论-差分约束-SPFA

    [bzoj2330]: [SCOI2011]糖果 恩..就是裸的差分约束.. x=1 -> (A,B,0) (B,A,0) x=2 -> (A,B,1)  [这个情况加个A==B无解的要特 ...

随机推荐

  1. 2.BIND服务基础及域主服务器配置

    一.BIND 现今使用最晚广泛的DNS服务器软件是BIND(Berkeley Internet Name Domain),最早由伯克利大学的一名学生编写,现在最新的版本是9,由ISC(Internet ...

  2. C# 表达式树学习笔记

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. Linux(centos) 下curl模拟Http get / post请求 [ curl ]

    一.get请求 curl "http://www.baidu.com"  如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地 curl -i "http:// ...

  4. 强化学习4-时序差分TD

    之前讲到强化学习在不基于模型时可以用蒙特卡罗方法求解,但是蒙特卡罗方法需要在每次采样时生产完整序列,而在现实中,我们很可能无法生成完整序列,那么又该如何解决这类强化学习问题呢? 由贝尔曼方程 vπ(s ...

  5. JavaScript和它父亲的故事

    附赠脱单秘籍:了解一些JavaScript的历史,聊天的时候说不好可以获得更多程序员小妹子的崇拜的哟~ ๑乛◡乛๑~ 阅读本文可以让你更好的理解什么是ECMAScript. 本次文章内容来自:< ...

  6. github咋用昂

    github-trend:https://github.com/trending github-usingway:https://zhuanlan.zhihu.com/p/41899093 githu ...

  7. dos命令:目录操作

    目录操作 一.cd语句 1.介绍 ​ 显示当前目录名或改变当前目录. 2.语法 CHDIR [/D] [drive:][path] CHDIR [..] CD [/D] [drive:][path] ...

  8. VS2010,MFC动态按钮和窗体背景图片,以及是静态文字控件透明,并避免静态文字刷新出现的重叠问题

    1.动态按钮的四种动作 1)正常 2)按下 3)滑过 4)失效 在MFC中,4个动作对应着四种位图bmp, 首先,将代表四种状态的位图加载入资源中,将对应的按钮设置为BitmapButton 第二,在 ...

  9. FCC JS基础算法题(7):Chunky Monkey(分割数组)

    题目描述: 把一个数组arr按照指定的数组大小size分割成若干个数组块. 例如:chunk([1,2,3,4],2)=[[1,2],[3,4]]; chunk([1,2,3,4,5],2)=[[1, ...

  10. 什么是lambda函数,它有什么好处

    编程中提到的lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是值匿名函数. python允许你定义一种单行的小函数.定义lambda函数的形式如下lambda参 ...