SCOI2011 糖果

来源:互联网 发布:淘宝客服服务回复 编辑:程序博客网 时间:2024/05/01 22:41

题目描述 Description

幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。

输入描述 Input Description

输入的第一行是两个整数N,K。
接下来K行,表示这些点需要满足的关系,每行3个数字,X,A,B。
如果X=1, 表示第A个小朋友分到的糖果必须和第B个小朋友分到的糖果一样多;
如果X=2, 表示第A个小朋友分到的糖果必须少于第B个小朋友分到的糖果;
如果X=3, 表示第A个小朋友分到的糖果必须不少于第B个小朋友分到的糖果;
如果X=4, 表示第A个小朋友分到的糖果必须多于第B个小朋友分到的糖果;
如果X=5, 表示第A个小朋友分到的糖果必须不多于第B个小朋友分到的糖果;

输出描述 Output Description

输出一行,表示lxhgww老师至少需要准备的糖果数,如果不能满足小朋友们的所有要求,就输出-1

样例输入 Sample Input

5 71 1 22 3 24 4 13 4 55 4 52 3 54 5 1

样例输出 Sample Output

11

数据范围及提示 Data Size & Hint
对于30%的数据,保证 N<=100
对于100%的数据,保证 N<=100000
对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N
曾经的省选题沦落到差分约束练习题╮(╯▽╰)╭,需要注意的地方是数据爆int,卡朴素spfa,加点特技就好233.
代码如下

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define ll long longusing namespace std;const int sz = 500010;int head[sz],nxt[sz];ll dis[sz];struct gtnd{    int t;    ll d;}l[sz];int tot = 1;deque < int > q;bool use[sz];int vis[sz];int n,m;ll read(){    ll x = 0 , f = 1;    char in = getchar();    while(in < '0' || in > '9')    {        if(in == '-')            f = -1;        in = getchar();    }    while('0' <= in && in <= '9')    {        x = x * 10 + in - '0';        in = getchar();    }    return x * f;}void build_edge(int f,int t,int d){    l[tot].t = t;    l[tot].d = d;    nxt[tot] = head[f];    head[f] = tot ++;}void start_work(){    n = read() , m = read();    for(int i = 1 ; i <= m ; i ++)    {        int x = read() , a = read() , b = read();        if(x == 1)            build_edge(a,b,0) , build_edge(b,a,0);        if(x == 2)            build_edge(a,b,1);        if(x == 3)            build_edge(b,a,0);        if(x == 4)            build_edge(b,a,1);        if(x == 5)            build_edge(a,b,0);    }    for(int i = 1 ; i <= n ; i ++)        build_edge(0,i,0);}bool spfa(){    for(int i = 1 ; i <= n ; i ++)        dis[i] = -214748364145145ll;    dis[0] = 0;    use[0] = 1;    q.push_back(0);    while(!q.empty())    {        int f = q.front();        q.pop_front();        use[f] = 0;        for(int i = head[f] ; i ; i = nxt[i])        {            int t = l[i].t;            if(dis[t] < dis[f] + l[i].d)            {                dis[t] = dis[f] + l[i].d;                vis[t] = vis[f] + 1;                if(vis[t] > n)                    return false;                if(!use[t])                {                    use[t] = 1;                    if(!q.empty())                    {                        if(t < q.front())                            q.push_front(t);                        else                            q.push_back(t);                    }                    else                        q.push_back(t);                }            }        }    }    return true;}void make_ans(){    ll ans = 0;    if(!spfa())    {        puts("-1");        return ;    }    for(int i = 1 ; i <= n ; i ++)        ans += dis[i];    ans += n;    printf("%lld\n",ans);}int main(){    start_work();    make_ans();    return 0;}
0 0
原创粉丝点击