您的位置:首页 > 编程语言 > C语言/C++

ZOJ2770 Burn the Linked Camp (差分约束与最短路)

2014-10-17 00:00 441 查看
本文出自: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
= 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图论 ACM c c++