POJ 3159 Candies(差分约束基础题,栈式SPFA)

Candies
Time Limit: 1500MS Memory Limit: 131072K
Total Submissions: 25818 Accepted: 7049

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 A, B and c in order, meaning that kid A believed that kid B should never get over c 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

 

Hint

32-bit signed integer type is capable of doing all arithmetic.
 
 
 
 
题意:有n个小朋友,给出m行,每行有A,B,c三个数。表示B最多比A多c个糖果。问第n个小朋友最多比第一个小朋友多几个糖果。
 
 
今天第一次知道差分约束问题,搜了几篇博文,大致了解了一下:
 
差分约束问题就是给一些类似如x-y<=k的约束条件,在满足这些条件下求解。
 
如图构建一个差分约束系统:
 
 
a,b,c为三个点,k1,k2,k3是边上的权值。
 
已知三个不等式  b-a<=k1,   c-b<=k2,    c-a<=k3,      要求出c-a的最大值。
 
由  c-b<=k2;   b-a<=k1   可得c-a<=k2+k1。   则比较k2+k1与k3的大小,当中小的值就是c-a的最大值。
 
 
在上例很容易看到求c-a的最大值实际上就是求a到c的最短路径。所以差分约束问题可以看做最短路问题的衍生,变形。
 
 
刚刚学差分约束,只能把在大牛博文中看到的好理解的东西在此复述一遍,有更多体会时再详述。
 
 
具体代码如下:(注意用队列写SPFA会超时)
 
 
 
<span style="font-size:12px;">#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f
#define maxn 30010
#define maxm 150010
int dis[maxn],visit[maxn],head[maxn];
int n,cnt;
struct node
{
	int to,val,next;
}edge[maxm];

void add(int a,int b,int c)
{
	edge[cnt].to=b;
	edge[cnt].val=c;
	edge[cnt].next=head[a];
	head[a]=cnt++;
}

void spfa()
{
	int i,u,v,stck[maxn];//数组模拟栈 
	int top=0;
	for(i=1;i<=n;++i)
	{
		dis[i]=INF;
		visit[i]=0;
	}
	dis[1]=0;
	stck[top++]=1;//进栈 
	visit[1]=1;
	while(top)
	{
		u=stck[--top];
		visit[u]=0;
		for(i=head[u];i!=-1;i=edge[i].next)
		{
			v=edge[i].to;
			if(dis[v]>dis[u]+edge[i].val)
			{
				dis[v]=dis[u]+edge[i].val;
				if(!visit[v])
				{
					stck[top++]=v;//出栈 
					visit[v]=1;
				}
			}
		}
	}
	printf("%d\n",dis[n]);
}

int main()
{
	int m,a,b,c;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		cnt=0;
		memset(head,-1,sizeof(head));
		while(m--)
		{
			scanf("%d%d%d",&a,&b,&c);
			add(a,b,c);
		}
		spfa();
	}
	return 0;
}</span>

 

你可能感兴趣的:(POJ 3159 Candies(差分约束基础题,栈式SPFA))