您的位置:首页 > 其它

ZOJ2770(差分约束系统学习)

2013-08-10 23:05 369 查看
Sn代表前n个军营的总人数
3 2
1000 2000 1000
1 2 1100
2 3 1300
1.每个兵营实际人数不能超过其容量,得到下面不等式
S1 - S0 <= 1000
S2 - S1 <= 2000
S3 - S2 <= 1000
2.每个兵营的实际人数大于等于0,得到下面不等式
S0 - S1 <= 0
S1 - S2 <= 0
S2 - S3 <= 0
3.第i个大营到第j个大营的士兵总数至少有k个,得到下面不等式
S0 - S2 <= -1100
S1 - S3 <= -1300
4.第i个大营到第j个大营的士兵总数不超过这些兵营容量的和,得到下面不等式
S2 - S0 <= 3000
S3 - S1 <= 3000
最终要求 Sn - S0 >= M , 转化为 S0 - S3 <= -M

1.Bellman_Ford 版本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <algorithm>
using namespace std;
#define inf 9999999
#define N 1005

#define M 23005
int size,n,m;
int dis
,vis
,head
,in
,sum
;
struct Edge
{
int v,w,next;
Edge(){}
Edge(int V,int W,int NEXT):v(V),w(W),next(NEXT){}
}edge[M];

void Init()
{
size = 0;
memset(head,-1,sizeof(head));
sum[0] = 0;
}

void InsertEdge(int u,int v,int w)
{
edge[size] = Edge(v,w,head[u]);
head[u] = size++;
}

bool spfa(int st)
{
for(int i=0; i<=n; i++)
{
vis[i] = 0;
dis[i] = inf;
in[i] = 0;
}
dis[st] = 0 ; vis[st] = 1;
queue<int> Q;
while(!Q.empty()) Q.pop();
Q.push(st);
in[st] ++;
while(!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = 0;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v = edge[i].v;
if(dis[v] > dis[u] + edge[i].w)
{
dis[v] = dis[u] + edge[i].w;
if(!vis[v])
{
vis[v] = 1;
in[v]++;
if(in[v] > n) return 0;
Q.push(v);
}
}
}
}
return 1;
}

int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
Init();
int u,v,w;
for(int i=1; i<=n; i++)
{
scanf("%d",&w);
InsertEdge(i-1,i,w);
InsertEdge(i,i-1,0);
sum[i] = sum[i-1] + w;
}
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&u,&v,&w);
InsertEdge(v,u-1,-w);
InsertEdge(u-1,v,sum[v]-sum[u-1]);
}
if(!spfa(n))  printf("Bad Estimations\n");
else  printf("%d\n",-dis[0]);
}
return 0;
}
View Code

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: