Bellman算法ZOJ2770

差分约束系统

c[n]表示每个点的容量,d[n]表示前n个点的容量和,x[n]表示第n个点的人数,s[n]表示前n个点的人数和。

因为是求最大值,左右约束条件写成小于的形式,求最短路。

约束条件:

1.s[i]-s[i-1]<=c[i],即s[i]<=s[i-1]+c[i];        增加边<i-1,i>=c[i];

2.s[i]-s[i-1]>=0, 即s[i-1]<=s[i]+0;        增加边<i,i-1>=0;

3,s[j]-s[i-1]>=k, 即s[i]<=s[j]-k;       增加边<j,i-1>=k;

4,s[j]-s[i-1]<=d[j]-d[i-1];即s[j]=s[i-1]+d[j]-d[i-1];  增加边<i-1,j>=d[j]-d[i-1];

5,s[n]-s[0]=dis[n]>=0,即s[0]<=s[n]+0, 可以直接设置dis[n]=0;

初始设置dis[i]=INF,i(1,n-1);

//复杂度为O(mn),可以存在负边,要判断是否存在负权的圈
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x7fffffff
#define maxl 22222
#define maxn 1005
using namespace std;
int d[maxn]={0};
struct Edg
{
    int u,v,w;
};

int dis[maxn];
Edg edg[maxl];
int n,m;
int edgnum;
void add(int u,int v,int w)
{
    edg[edgnum].u=u;
    edg[edgnum].v=v;
    edg[edgnum].w=w;
    edgnum++;
}
bool bellman_ford()
{
    int t,u,v,w;
    for(int i=1;i<n;i++) dis[i]=INF;
    dis[n]=0;//dis[n]=0;S[n]>=S[0],S[0]-S[n]<=0,dis[n]=0;
    for(int i=1; i<=n; i++)/*假设第k条边的起点是u,终点是v,以下循环考虑第k条边是否会使得源点v0到v的
最短距离缩短,即判断dist[edges[k].u] + edges[k].w < dist[edges[k].v] 是否成立*/
    {
        for(int k=0; k<edgnum; k++)
        {
            u=edg[k].u,v=edg[k].v,w=edg[k].w;
            if(dis[u]!=INF&&dis[u]+w<dis[v])
            {
                dis[v]=dis[u]+w;
            }
        }
    }
    for(int k=0; k<edgnum; k++)/*以下是检查,若还有更新则说明存在无限循环的负值回路*/
    {
        u=edg[k].u,v=edg[k].v,w=edg[k].w;
        if(dis[u]!=INF&&dis[u]+w<dis[v])
        {
            return false;
        }
    }
    return true;
}
int main()
{
    int u,ii,jj,c;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        edgnum=0;
        dis[0]=0;
        d[0]=0;//d表示前n个点个容量和
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&c);
            add(i-1,i,c);
            add(i,i-1,0);
            d[i]=d[i-1]+c;//前i个点的容量
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&ii,&jj,&c);//i,j
            add(jj,ii-1,-c);
            add(ii-1,jj,d[jj]-d[ii-1]);
        }
        if(bellman_ford())
        printf("%d\n",dis[n]-dis[0]);
        else
        printf("Bad Estimations\n");
    }
    return 0;
}


你可能感兴趣的:(差分约束系统)