zoj 2770 Burn the Linked Camp(火烧连营)

来源:互联网 发布:苹果7没有4g网络怎么办 编辑:程序博客网 时间:2024/04/27 12:10

题意:陆逊已知刘备的每个大营最多能容纳Ci个士兵,并且可以估计到第i个大营到第j个大营至少有多少士兵,求刘备最少有多少个士兵。


分析:根据给出的数据我们可以得到一系列不等式组,考虑采用差分约束系统求解。以第一组测试数据解释差分约束系统及构造求解。

设三个军营的人数分别为A1,A2,A3,容量为C1,C2,C3,前n个军营的总人数为Sn,则可以列出以下不等式组。

⑴第i个大营到第j个大营士兵总数至少有k个。

S2 - S0 >= 1100  --->  S0 - S2 <= -1100

S3 - S1 >= 1300  --->  S1 - S3 <= -1300

⑵第i个大营到第j个大营不超过这些兵营容量只和,设d[i]为前i个大营容量总和。

S2 - S0 <= d[2] - d[0] = 3000

S3 - S1 <= d[3] - d[1] = 3000

⑶每个兵营实际人数不超过容量。

A1 <= 1000 ---> S1 - S0 <= 1000

A2 <= 2000 ---> S2 - S1 <= 2000

A3 <= 1000 ---> S3 - S2 <= 1000

⑷Ai>=0

S0 - S1 <= 0

S1 - S2 <= 0

S2 - S3 <= 0

把以上不等式组整理好后,我们就可以构造出一个有向图,构造好图后,我们要求的是 S3 - S0的最小值,即 S3 - S0 >= M  ---> S0 -  S3 <= -M,求S3到S0的最短路径,长度为-M,最终结果就是M。若无最短路径则输出Bad Estimations。

以上参考自:《图论算法理论、实现及应用》---北京大学出版社


第一道差分约束的题,做完还不是很明白 - -。


代码

#include <iostream>#include <cstdio>#include <vector>#include <queue>using namespace std;const long long inf = 10000000000000LL;const int maxn = 10005;struct node{int v;long long w;node(int _v, long long _w){v = _v; w = _w; }};int n,m;int c[maxn]; //每个兵营的人数限制long long d[maxn]; //前i个兵营的人数总和vector<node> list[maxn];long long dist[maxn];//for spfaint cnt[maxn];//判断负环 bool inq[maxn];bool input(){if(scanf("%d%d",&n,&m) == EOF) return false;for(int i = 1; i <= n; i++) scanf("%d",&c[i]);//求和 d[0] = 0;for(int i = 1; i <= n; i++) d[i] = d[i-1] + c[i];//clearfor(int i = 0; i <= n; i++) list[i].clear();int u,v,w;for(int i = 0; i< m; i++){scanf("%d%d%d",&u,&v,&w);//情形1 list[v].push_back(node(u-1,-w));//情形2list[u-1].push_back(node(v,d[v]-d[u-1]));}for(int i = 1; i <= n; i++){//情形3list[i-1].push_back(node(i,c[i]));//情形4list[i].push_back(node(i-1,0));}return true;}bool spfa(int s){queue<int> q;for(int i = 0; i <= n; i++){dist[i] = inf;inq[i] = false;cnt[i] = 0;}dist[s] = 0;q.push(s);cnt[s]++;while(!q.empty()){int u = q.front(); q.pop(); inq[u] = false;if(cnt[u] >= n) return false;for(int i = 0; i < list[u].size(); i++){int v = list[u][i].v;long long w = list[u][i].w;if(dist[u] + w < dist[v]){dist[v] = dist[u] + w;if(!inq[v]){q.push(v); inq[v] = true; cnt[v]++;}}}}return true;}void solve(){if(spfa(n)){printf("%lld\n",-dist[0]);}else{printf("Bad Estimations\n");}}int main(){while(input()){solve();}return 0;}


0 0
原创粉丝点击