首页 > 代码库 > ZOJ2770 Burn the Linked Camp (差分约束与最短路)
ZOJ2770 Burn the Linked Camp (差分约束与最短路)
本文出自:http://blog.csdn.net/svitter
题意:给你n个营地,每个营地最多Cn个人,然后告诉你i~j个营地中,最少有k个人。让你求一共有多少个士兵。
本题目为差分约束,差分约束的关键就在于解线性不等式。
把线性不等式转换为图中的松弛操作思想。
简单的例子:dis[v] <= dis[u] + (u, v) 如是。
做这个题目的时候其实没有仔细想想为什么,就只是单纯的列出不等式然后导入到边的关系,就认为可以A出了。
然后很容易就做错了- -
不等式为:
s [ i - 1 ] <= s [ j ] + ( -k );(2)
s [ i - 1 ] <= s [ i ] (3)
s [ i ] <= s [ i - 1 ] + c [ i ]; (4)
如是。s [ i ]表示从1到i一共有多少个士兵。Xi = s [ i ] - s [ i - 1 ] ;
此时,要选择n作为源点。为什么?
如果选择0为源点,即dis [ n ] - dis [ 0 ] <= dis(0 , n)
因为dis [ 0 ] 是 0 ,所以求出dis [ n ] <=dis(0 , n);
如果选择n为源点,即dis [ 0 ] -dis [ n ] <= dis(n , 0) 即dis[ 0 ] >=dis[ n ] - dis(n , 0)
因为dis [ n ] = 0, 则dis [ 0 ] >= - dis(n , 0);
第一个求出的是全部士兵最大值,第二个求出的是全部士兵最小值。
也正是媛姐所说:http://blog.csdn.net/zxy_snow/article/details/6173375(我不认识她 = =)
//from : blog.csdn.net/svitter #include <iostream> #include <cstdio> #include <cstring> using namespace std; #define INF 0x1f1f1f1f //k<2^31 struct Edge { int u; int v; int w; }; Edge edge[15000]; int res[1001]; bool bellman(int n, int m, int src) { memset(res, 0x1f, sizeof(res)); res[n] = 0; int i, j; for(i = 0; i <= n; i++) { for(j = 0; j < m; j++) { if(res[edge[j].u] < INF && res[edge[j].u] + edge[j].w < res[edge[j].v]) res[edge[j].v] = res[edge[j].u] + edge[j].w; } } for(i = 0; i < n; i++) { for(j = 0; j < m; j++) { if(res[edge[j].u] < INF && res[edge[j].u] + edge[j].w < res[edge[j].v]) return 1; } } return 0; } void ace() { //work point; int i, j, k; //case int n, m, num; //num int u, v, w; while(~scanf("%d%d", &n, &m)) { num = 1; for(i = 0; i < n; i ++) { scanf("%d", &w); //res[num-1] <= res[num] + 0 edge[i].u = num; edge[i].v = num - 1; edge[i].w = 0; //res[num] <= res[num-1] + Ci edge[i+n].u = num - 1; edge[i+n].v = num; edge[i+n].w = w; num++; } m += 2 * n; for(i = 2 * n; i < m; i++) { scanf("%d%d%d", &u, &v, &w); //res[u-1] <= res[v] - (v, u); edge[i].u = v; edge[i].v = u - 1; edge[i].w = -w; } if(bellman(n, m, 1)) printf("Bad Estimations\n"); else printf("%d\n", -res[0]); }//end of n } int main() { ace(); return 0; }
ZOJ2770 Burn the Linked Camp (差分约束与最短路)