Bellman算法ZOJ2770

来源:互联网 发布:js timer控件 编辑:程序博客网 时间:2024/04/29 12:56

差分约束系统

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 1005using 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;}


原创粉丝点击