Candies

【题目描述】

有N个人在分糖果,且其符合M条规则,每条规则表示为一个如下格式的不等式:

B-A≤C(B所得糖果数比A所得糖果数至多多C个)

现询问N比1至多多几个糖果。

【输入描述】

第一行输入两个整数N、M;

接下来m行,每行输入三个整数A、B、C。

【输出描述】

输出一个数,表示答案。

【输入样例】

2 2

1 2 5

2 1 4

【输出样例】

5

源代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct Node1
{
    int S,To,Next;
}Edge[150001];
struct Node2
{
    int A,B,C;
}Map[150001];
deque <int> Q;
int m,n,Num(0),i[30001],Head[30001]={0};
bool In[30001]={0};
void Add(int t1,int t2,int t)
{
    Edge[++Num].S=t;
    Edge[Num].To=t2;
    Edge[Num].Next=Head[t1];
    Head[t1]=Num;
}
int main() //差分约束系统。
{
    memset(i,0x3f,sizeof(i));
    scanf("%d%d",&n,&m);
    for (int a=0;a<m;a++)
      scanf("%d%d%d",&Map[a].A,&Map[a].B,&Map[a].C);
    random_shuffle(Map,Map+m); //再说一遍,你卡不了我蛤蛤蛤,毛嫩的后生!
    for (int a=0;a<m;a++)
      Add(Map[a].A,Map[a].B,Map[a].C);
    i[1]=0;
    In[1]=true;
    Q.push_back(1);
    while (!Q.empty()) //SPFA+SLF。
    {
        int t=Q.front();
        In[t]=false;
        Q.pop_front();
        for (int a=Head[t];a;a=Edge[a].Next)
        {
            int T=Edge[a].To;
            if (i[T]>i[t]+Edge[a].S)
            {
                i[T]=i[t]+Edge[a].S;
                if (!In[T])
                {
                    In[T]=true;
                    if (!Q.empty()&&i[T]<i[Q.front()])
                      Q.push_front(T);
                    else
                      Q.push_back(T);
                }
            }
        }
    }
    printf("%d",i[n]);
    return 0;
}

/*
    最近刚接触差分约束,挺神奇的一个东西,把数论转化成了最短路。
    举个例子:
        B-A <= k1
        C-B <= k2
        C-A <= k3
    不妨画个图:
        A --> B = k1
        B --> C = k2
        A --> C = k3
    可以发现,C-A <= min(k1+k2,k3),即是最短路。
*/
原文地址:https://www.cnblogs.com/Ackermann/p/6020517.html