约分差束 例题 ZOJ 2770 火烧连营

来源:互联网 发布:springboot 切面编程 编辑:程序博客网 时间:2024/04/20 01:15
题目来源:
ZOJ Monthly, October 2006, ZOJ2770
题目描述:
大家都知道,三国时期,蜀国刘备被吴国大都督陆逊打败了。刘备失败的原因是刘备的错误
决策。他把军队分成几十个大营,每个大营驻扎一队部队,又用树木编成栅栏,把大营连成一片,
称为连营。
让我们回到那个时代。陆逊派了很多密探,获得了他的敌人-刘备军队的信息。通过密探,
他知道刘备的军队已经分成几十个大营, 这些大营连成一片 (一字排开), 这些大营从左到右用 1
n 编号。第 i 个大营最多能容纳 Ci 个士兵。而且通过观察刘备军队的动静,陆逊可以估计到从第 i
个大营到第 j 个大营至少有多少士兵。最后,陆逊必须估计出刘备最少有多少士兵,这样他才知
图论算法理论、实现及应用
- 196 -
道要派多少士兵去烧刘备的大营。
输入描述:
输入文件中有多个测试数据。每个测试数据的第一行,有两个整数 n(0<n1000)m(0m
10000)。第二行,有 n 个整数 C1Cn。接下来有 m 行,每行有 3 个整数 i, j, k(0<ijn, 0
k<231),表示从第 i 个大营到第 j 个大营至少有 k 个士兵。
输出描述:
对每个测试数据,输出一个整数,占一行,为陆逊估计出刘备军队至少有多少士兵。然而,
陆逊的估计可能不是很精确,如果不能很精确地估计出来,输出"Bad Estimations"
样例输入: 样例输出:
3 2
1000 2000 1000
1 2 1100
2 3 1300
3 1
100 200 300
2 3 600
1300
Bad Estimations

 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int n,m; 6 struct node{ 7     int from,to,value; 8 }e[25000]; 9 int ei,c[1200],d[1200],dis[1200];// dis 最短路10 // d  阵营前缀和  c 每个阵营的最大人数11 void init()12 {13     memset(dis,0x3f,sizeof(dis));14     d[0]=0;dis[n]=0;ei=0;15 }16 bool check()17 {18     for(int i=0;i<n;i++){19         for(int j=0;j<ei;j++){20             if(dis[e[j].to]>dis[e[j].from]+e[j].value && dis[e[i].from]!=0x3f)// 松弛 21               dis[e[j].to]=dis[e[j].from]+e[j].value;22         }23     }24     for(int i=0;i<ei;i++){25         if(dis[e[i].from]+e[i].value<dis[e[i].to] && dis[e[i].from]!=0x3f)26           return false;27     }28     return true;29 }30 int main()31 {32     while(scanf("%d%d",&n,&m)!=EOF)33     {34         init();35         for(int i=1;i<=n;i++){36             scanf("%d",&c[i]);37             e[ei].from=i-1;e[ei].to=i;e[ei].value=c[i];ei++;//从这个阵营到后面一个阵营最多c[i]个人38             e[ei].from=i;e[ei].to=i-1;e[ei].value=0;ei++;//从这个后面一个阵营到这个阵营最少0个人39             d[i]=d[i-1]+c[i];}40         int u,v,w;41         for(int i=0;i<m;i++){42             scanf("%d%d%d",&u,&v,&w);43             e[ei].from=v;e[ei].to=u-1;44             e[ei].value=w*(-1);ei++; 45             e[ei].from=u-1;e[ei].to=v;e[ei].value=d[v]-d[u-1];ei++;46             }47         if(!check()) printf("Bad Estimations\n");48         else printf("%d\n",dis[n]-dis[0]);49     } 50     return 0; 51 }

 

思路:把各个条件处理成一个不等式(最好全是大于或者全是小于),然后构造有向图,跑一边最短路检验

 

0 0