POJ3159 用最短路解决差分约束问题

vCoders

POJ3159(最短路)

Candies

Time Limit: 1500MS   Memory Limit: 131072K
Total Submissions: 27051   Accepted: 7454

Description

During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher brought the kids of flymouse’s class a large bag of candies and had flymouse distribute them. All the kids loved candies very much and often compared the numbers of candies they got with others. A kid A could had the idea that though it might be the case that another kid B was better than him in some aspect and therefore had a reason for deserving more candies than he did, he should never get a certain number of candies fewer than B did no matter how many candies he actually got, otherwise he would feel dissatisfied and go to the head-teacher to complain about flymouse’s biased distribution.

snoopy shared class with flymouse at that time. flymouse always compared the number of his candies with that of snoopy’s. He wanted to make the difference between the numbers as large as possible while keeping every kid satisfied. Now he had just got another bag of candies from the head-teacher, what was the largest difference he could make out of it?

Input

The input contains a single test cases. The test cases starts with a line with two integers N and M not exceeding 30 000 and 150 000 respectively. N is the number of kids in the class and the kids were numbered 1 through N. snoopy and flymouse were always numbered 1 and N. Then follow M lines each holding three integers AB and c in order, meaning that kid A believed that kid B should never get overc candies more than he did.

Output

Output one line with only the largest difference desired. The difference is guaranteed to be finite.

Sample Input

2 2
1 2 5
2 1 4

Sample Output

5

题目大意:有n位同学,他们按1--n号进行排号进行分糖果活动,题目给出m种约束关系,A B  C表示,孩子B所拥有的糖果数量不会比孩子A多c个,即p[B] - p[A] <=c,求1号孩子与n号孩子最多糖果差多少(其实就是差分约束问题

我们可以从A到B建立一条权值为c的边,这样就再进而套用最短路的模板

#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
const int N=151000;
const int INF=0x3f3f3f3f;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
struct node
{
    int to,w,next;
}num[N];
int head[N];
bool vis[N];
int dis[N];
int tot;
int n,m;
void add(int u,int v,int w)
{
    num[tot].to=v;
    num[tot].w=w;
    num[tot].next=head[u];
    head[u]=tot++;
}
void SPFA()
{
    memset(dis,INF,sizeof dis);
    memset(vis,0,sizeof vis);
    vis[1]=1;
    dis[1]=0;
    stack< int > s;
    s.push(1);
    while(!s.empty())
    {
        int now=s.top();s.pop();//这里一定是要先pop一下,因为栈的存储方式与队列是不同的
        for(int i=head[now];i!=-1;i=num[i].next)
        {
            if(dis[num[i].to]>num[i].w+dis[now])//约束条件
            {
                dis[num[i].to]=dis[now]+num[i].w;
                if(!vis[num[i].to])
                    vis[num[i].to]=1,s.push(num[i].to);
            }
        }
        vis[now]=0;
    }
    printf("%d\n",dis[n]);
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        tot=1;
        memset(num,0,sizeof num);
        memset(head,-1,sizeof head);
        rep(i,1,m)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        SPFA();
    }
}

还有就是这题可能由于数据量太大,导致用队列超时了,戳这里看解释

猜你喜欢

转载自blog.csdn.net/c___c18/article/details/82152064
今日推荐