ZOJ 2770 Burn the Linked Camp 差分约束 (转)

It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Bei‘s wrong decision that he divided his large troops into a number of camps, each of which had a group of armies, and located them in a line. This was the so-called "Linked Camps".

Let‘s go back to that time. Lu Xun had sent many scouts to obtain the information about his enemy. From his scouts, he knew that Liu Bei had divided his troops into n camps, all of which located in a line, labeled by 1..n from left to right. The ith camp had a maximum capacity of Ci soldiers. Furthermore, by observing the activities Liu Bei‘s troops had been doing those days, Lu Xun could estimate the least total number of soldiers that were lived in from the ith to the jth camp. Finally, Lu Xun must estimate at least how many soldiers did Liu Bei had, so that he could decide how many troops he should send to burn Liu Bei‘s Linked Camps.

Input:

There are multiple test cases! On the first line of each test case, there are two integers n (0<n<=1,000) and m (0<=m<=10,000). On the second line, there are n integers C1??Cn. Then m lines follow, each line has three integers i, j, k (0<i<=j<=n, 0<=k<2^31), meaning that the total number of soldiers from the ith camp to the jth camp is at least k.

Output:

For each test case, output one integer in a single line: the least number of all soldiers in Liu Bei‘s army from Lu Xun‘s observation. However, Lu Xun‘s estimations given in the input data may be very unprecise. If his estimations cannot be true, output "Bad Estimations" in a single line instead.

Sample Input:

3 2 1000 2000 1000 1 2 1100 2 3 1300 3 1 100 200 300 2 3 600 

Sample Output:

1300 Bad Estimations

题目大意:

大家都知道,三国时期,蜀国刘备被吴国大都督陆逊打败了。刘备失败的原因是因为刘备的错误决策。他把部队分成几十个大营,每个大营驻扎一队部队,又用树木编成栅栏,把大营连成一片,称为连营。
让我们回到那个时代。陆逊派了很多密探,获得了他的敌人-刘备的信息。通过密探,他知道刘备的部队已经分成几十个大营,这些大营连成一片(一字排开),这些大营从左到右用1...n编号。第i个大营最多能容纳Ci个士兵。而且通过观察刘备军队的动静,陆逊可以估计到从第i个大营到第j个大营至少有多少士兵。最后,陆逊必须估计出刘备最少有多少士兵,这样他才知道要派多少士兵去烧刘备的大营。
为陆逊估计出刘备军队至少有多少士兵。然而,陆逊的估计可能不是很精确,如果不能很精确地估计出来,输出"Bad Estimations"

对于样例数据:

数学模型为:设3个军营的人数分别为A1, A2, A3,容量为C1, C2, C3,前n个军营的总人数为Sn,则有:

1. 则根据第i个大营到第j个大营士兵总数至少有k个,得不等式组(1):
S2 – S0 >= 1100 等价于 S0 – S2 <= -1100
S3 – S1 >= 1300 等价于 S1 – S3 <= -1300

2. 又根据实际情况,第i个大营到第j个大营的士兵总数不超过这些兵营容量之和,设d[i]为前i个大营容量总和,得不等式组(2):
S2 – S0 <= d[2] – d[0] = 3000
S3 – S1 <= d[3] – d[1] = 3000

3. 每个兵营实际人数不超过容量,得不等式组(3)
A1 <= 1000 等价于 S1 – S0 <= 1000
A2 <= 2000 等价于 S2 – S1 <= 2000
A3 <= 1000 等价于 S3 – S2 <= 1000

4. 另外由Ai>=0,又得到不等式组(4)
S0 – S1 <= 0
S1 – S2 <= 0
S2 – S3 <= 0
求A1+A2+A3的最小值(即S3 – S0的最小值)

构造好网络之后,最终要求什么?
要求S3 – S0的最小值,即要求不等式:
S3 – S0 >= M
中的M,转化成:
S0 – S3 <= -M
即求S3到S0的最短路径,长度为-M
求得-M为-1300,即M为1300

  1. #include <stdio.h>
  2. #define INF 9999999
  3. int n,m,dist[1010],c[1010],d[1010],ei;
  4. struct eg
  5. {
  6. int u,v,w;
  7. }edges[23000];
  8. void init()
  9. {
  10. ei=0;
  11. int i;
  12. for(i=0;i<=n;i++)
  13. dist[i]=INF;
  14. d[0]=0;
  15. dist[n]=0;
  16. }
  17. bool bell()
  18. {
  19. int i,k,t;
  20. for(i=0;i<n;i++)
  21. {
  22. for(k=0;k<ei;k++)
  23. {
  24. t=dist[edges[k].u]+edges[k].w;
  25. if(dist[edges[k].u]!=INF&&t<dist[edges[k].v])
  26. dist[edges[k].v]=t;
  27. }
  28. }
  29. for(k=0;k<ei;k++)
  30. {
  31. if(dist[edges[k].u]!=INF&&dist[edges[k].u]+edges[k].w<dist[edges[k].v])
  32. return false;
  33. }
  34. return true;
  35. }
  36. int main()
  37. {
  38. while(scanf("%d%d",&n,&m)!=EOF)
  39. {
  40. init();
  41. int i,u,v,w;
  42. for(i=1;i<=n;i++)
  43. {
  44. scanf("%d",&c[i]);
  45. edges[ei].u=i-1;
  46. edges[ei].v=i;
  47. edges[ei].w=c[i];
  48. ei++;
  49. edges[ei].u=i;
  50. edges[ei].v=i-1;
  51. edges[ei].w=0;
  52. ei++;
  53. d[i]=c[i]+d[i-1];
  54. }
  55. for(i=0;i<m;i++)
  56. {
  57. scanf("%d%d%d",&u,&v,&w);
  58. edges[ei].u=v;
  59. edges[ei].v=u-1;
  60. edges[ei].w=-w;
  61. ei++;
  62. edges[ei].u=u-1;
  63. edges[ei].v=v;
  64. edges[ei].w=d[v]-d[u-1];
  65. ei++;
  66. }
  67. if(!bell())
  68. printf("Bad Estimations\n");
  69. else printf("%d\n",-dist[0]);
  70. }
  71. return 0;
  72. }
				
时间: 2024-10-27 17:58:56

ZOJ 2770 Burn the Linked Camp 差分约束 (转)的相关文章

ZOJ 2770 Burn the Linked Camp 差分约束+SPFA

第一道正儿八经的差分约束题 有排成一列的n个点,首先告诉你每个点的值最多是多少(最少显然要大于0),然后告诉你m段i,j,k,表示第i个点到第j个点的值的和至少有k,问你总和至少为多少. 要注意的是,告诉你的所有关系式都不要忘记建边,一开始漏了大于0的条件调半天o(╯□╰)o 不等式的形式是a-b<=c这样的= = 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <

ZOJ 2770 Burn the Linked Camp 差分约束

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2770 Burn the Linked Camp Time Limit: 2 Seconds      Memory Limit: 65536 KB It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeate

zoj2770 Burn the Linked Camp --- 差分约束

有n个营地,每个营地至多容纳Ci人,给出m个条件:第i到第j个营地之间至少有k人. 问n个营地总共至少有多少人. 此题显然差分约束,要求最小值,则建立x-y>=z方程组,建图求最长路. 用d[i]表示[1,i]个帐篷中一共多少人,根据题意可得到不等关系: 1.0<=d[i]-d[i-1]<=C[i] 2.d[j]-d[i]>=k 此外,我们添加0为附加结点,则0到其他点也要建边. 再求解0为源点的最长路即可. 我的坑点是,判负环返回0,否则返回d[n]. 而d[n]本身就可能是0.

ZOJ 2770 Burn the Linked Camp( 差分约束啊 )

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1770 It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Bei'

zoj 2770 Burn the Linked Camp

今天刚刚学差分约束系统.利用最短路求解不等式.世界真的好奇妙!感觉不等式漏下几个会导致WA!! #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; const int maxn = 1111; vector<int>ljb[ma

Burn the Linked Camp(bellman 差分约束系统)

Burn the Linked Camp Time Limit: 2 Seconds      Memory Limit: 65536 KB It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Be

ZOJ2770 Burn the Linked Camp(差分约束系统)

区间和一定要联系到前缀和. 这题,把前缀和看作点,从s0到sn: 对于每一个营地i的容量capi,有这么个关系si-si-1<=capi: 对于每一个区间的评估i,j,k,有sj-si-1>=k,即si-1-sj<=k: 接下来就是连边了,对于v<=u+w由u向v连权w的边,超级源向n+1个点连权0的边. 最后跑SPFA,如果出现负环则无解:而有解的话,所求答案就在d[sn]里,不过因为题目的前缀和是非负整数且要求的最少,所以就要让d中所有数都同时加上合适的数得到另一个真正所求的解

差分约束小结

ZOJ 2770 Burn the Linked Camp /* ZOJ 2770 Burn the Linked Camp 差分约束 */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int MAXN = 1009; struct Edge { int v, ne, c; } G[MAXN*MAXN]

ZOJ– 2770Burn the Linked Camp单源最短路径差分约束系统

ZOJ Problem Set – 2770 Burn the Linked Camp 题目的大意为: 陆逊侦查得知刘备将自己的军队分为N个营,从左到右编号为1,2,3…N.第i个营有最大士兵数Ci,通过一段时间的观察,陆逊可以估算至少有k个士兵住在第i到第j个营地,最后陆逊必须要估算刘备的军队至少有多少士兵,以便应对. 输入: 有多个测试案例,在每个测试案例的第一行,有两个整数N(0<n<=1000)和M(0 <= M = 10000).第二行中,有n个整数C1…CN.然后M行,每行有