zoj 3668 差分约束

来源:互联网 发布:数据分析属于哪一类 编辑:程序博客网 时间:2024/05/19 16:21

题意:给定L,R ,A,B; 表示序列从L到R的和>=A  , < =B。并输出序列最大的取值,误解输出  "The spacecraft is broken!"

查分约束:  u---->v 建条边 ,则有dis( v ) <=dis(u) +w(u,v);  即dis (v)- dis(u)< = w(u,v);

sum【R】表示0到R的和。 则sum【R】 - sum【L-1】 >= A; sum【R】 - sum【L-1】<=B;

   写成小于等于的形式 。sum【L-1】 - sum【R】 < = - A ;

 

#include<cstdio>#include<cstring>#include<iostream>#include<stack>using namespace std;const int inf=0x3f3f3f3f;const int N=1005;struct Point{    int v,w;    int next;}edge[50000];int vis[N],head[N],cnt[N],dis[N];int n,tot;void add(int u,int v,int w){    edge[tot].v=v;    edge[tot].w=w;    edge[tot].next=head[u];    head[u]=tot++;}bool spfa(int s){    for(int i=0;i<=n+1;i++) dis[i]=inf;    memset(vis,0,sizeof(vis));    memset(cnt,0,sizeof(cnt));    dis[s]=0;    vis[s]=1;    ++cnt[s];    stack<int>S;    S.push(s);    while(!S.empty())    {        int u=S.top();S.pop();        vis[u]=0;        for(int i=head[u];i!=-1;i=edge[i].next)        {            int v=edge[i].v;            int w=edge[i].w;            if(dis[v]>dis[u]+w)            {                dis[v]=dis[u]+w;                if(!vis[v])                {                    vis[v]=1;                    if(++cnt[v]>n) return false;                    S.push(v);                }            }        }    }    return true;}int main(){    freopen("Input.txt","r",stdin);    int m,i;    while(~scanf("%d%d",&n,&m))    {        tot=0;        memset(head,-1,sizeof(head));        int a,b,c,d,cc=0;        for(i=1;i<=m;i++)        {            scanf("%d%d%d%d",&a,&b,&c,&d);            if(c>d) cc=1;            add(a-1,b,d); add(b,a-1,-c); //建边        }        if(cc==1) { puts("The spacecraft is broken!"); continue;}        for(i=1;i<=n;i++)  //保证图的连通性。          add(i-1,i,10000) , add(i,i-1,10000);        bool flag=spfa(0);//0为源点。        if(flag)        {            for(i=0;i<n;i++)             printf("%d ",dis[i]-dis[i-1]);            printf("%d\n",dis[n]-dis[n-1]);        }        else puts("The spacecraft is broken!");    }    return 0;}