您的位置:首页 > 其它

zoj 2770 差分约束

2014-04-06 21:16 676 查看
/*
题意:给出N个营地,每个营地最多可容纳Ci人,给出m个三元组i,j,k分别表示当前营地从i到j至少有
k个人,问N个营地总共至少有多少人

题解:差分约束(SPFA)
题目中给出的很多条件都是约束的条件,例如最多有Ci个人,最少有k个人,问的问题也同样是最少多
少人,当所有给出的都是限制条件,然后自然会写出一些不等式,然后就可以联想到用差分系统来做
(马后炮的想法,当时想的时候也是没有考虑用差分系统),然后就是从题目中找出不等式:
设x[i] 为第i个营的人数,s[i] = x[1] + x[2] + … + x[i], s[0] = 0
Ci 有: 0 <= s[i] – s[i-1] <= Ci
i, j, k有: s[j] – s[i-1] >= k
还有: s[i] >= 0 (1 <= i <= n) , 即 s[i] – s[0] >= 0
因为题目要求的是最小值,因此需要转换为求最长路,不等式要全变成s[i]-s[j] >= t的形式,然后
建图求最长路即可(为什么是求最长路而不是最短路,其实可以通过s[i]-s[j] >= t思考,因为要求
的是一个最小值,其中的s[i]-s[j]>=t表示至少大于某个给出值,这样在求的时候才会有一个极限,
否则以s[i]-[j]<=t的形式去求,则值可以变成负数无限的小,从而无法求出答案,而首先给出一个限
定的最小值的形式,这样就能求出最小值,至于求最长还是求最短路就从不等式的形式去判断,这个
想法纯属YY,没有科学证明)
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>

#define clr(a,b) (memset(a,b,sizeof(a)))
#define cpy(a,b) (memcpy(a,b,sizeof(b)))
using namespace std;

const int NV = 1005;
const int NE = 15005;
const int INF = 0x7f7f7f7f;

int n;
int dis[NV],head[NV],insum[NV];
bool in[NV];
int SZ;
struct edge {
int v,d,next;
}E[NE];

inline void init(int nn) {
n = nn;
SZ = 0;
clr(head,-1);
clr(insum,0);
clr(in,false);
clr(dis,0x7f);
}
inline bool relax(int u,int v,int w) {
if(dis[v] == INF || dis[u] + w > dis[v]) {//大于,求最长路
dis[v] = dis[u] + w;
return true;
}
return false;
}
inline bool spfa(int start) {
int i;
queue<int>q;
dis[start] = 0;
q.push(start);
while(!q.empty()) {
int u = q.front();
q.pop();
in[u] = false;
for(i = head[u];i != -1;i = E[i].next) {
int v = E[i].v;
if(relax(u,v,E[i].d) && !in[v]) {
in[v] = true;
insum[v]++;
if (insum[v] >= n)
return false;
q.push(v);
}
}
}
return true;
}
inline void insert(int from,int to,int dis) {
E[SZ].v = to;
E[SZ].d = dis;
E[SZ].next = head[from];
head[from] = SZ ++;
}
int main(void)
{
int m;
while (~scanf("%d%d",&n,&m))
{
init(n);
for(int i=1; i<=n; i++)
{
int c;
scanf("%d",&c);
insert(i-1,i,0);
insert(i,i-1,-c);
insert(0,i,0);
}
while (m--)
{
int i,j,k;
scanf("%d%d%d",&i,&j,&k);
insert(i-1,j,k);
}
if (spfa(0))
printf("%d\n",dis
);
else
printf("Bad Estimations\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: