简、易-sachinKung

导航

【差分约束】福州2010 05月赛 Problems B Cows Arrangement&foj1898

差分约束

约束条件

s[i+1]-s[i]>=1;

s[n]-s[1]<=100000000

ML    a b   c

       s[b]-s[a]<=c

MD   a b   c

      s[b]-s[a]>=c

很显然是差分约束

最大值:

   s[i]-s[i+1]<=-1;

s[n]-s[1]<=100000000

s[b]-s[a]<=c

s[a]-s[b]<=-c

最小值值反向建图

当然求的时候就没有必要建两次题,一次bellman_ford 就行了

//============================================================================

// Name        : fzu201005B.cpp

// Author      : Ncbody

// Version     :

// Copyright   : Your copyright notice

// Description : Hello World in C++, Ansi-style

//============================================================================

#include <iostream>

#include <stdio.h>

#include <string.h>

#include <math.h>

using namespace std;

#define maxn 1005

const int INF=214748364;

struct Edge{

    int u,v;

    int w;

}edge[maxn*505];

int n,m,d,Eind;

void addedge(int u,int v,int w)

{

    edge[Eind].u=u;

    edge[Eind].v=v;

    edge[Eind].w=w;

    Eind++;

}

int dist2[maxn],dist1[maxn];

bool bellman(){

    bool flag2,flag1;

    int i,j;

    for(i=0;i<=n;i++)

        dist2[i]=INF,dist1[i]=-INF;

    dist2[1]=0;

    dist1[1]=0;

    for(i=1;i<=n;i++)

    {

        flag2=true;flag1=true;

        for(j=0;j<Eind;j++)

        {

            int u=edge[j].u;

            int v=edge[j].v;

            int w=edge[j].w;

            if(dist2[u]<INF&&dist2[v]>dist2[u]+w)

            {

                flag2=false;

                dist2[v]=dist2[u]+w;

            }

            if(dist1[v]>-INF&&dist1[u]<dist1[v]-w)

            {

                flag1=false;

                dist1[u]=dist1[v]-w;

            }

        }

        if(flag2&&flag1)break;

    }

    return flag2&&flag1;

}

int main() {

    int T,t;

    int i,a,b,c;

    scanf("%d",&T);

    for(t=1;t<=T;t++)

    {

        scanf("%d%d%d",&n,&m,&d);

        Eind=0;

        for(i=1;i<n;i++)

            addedge(i+1,i,-1);

        addedge(1,n,100000000);

        while(m--)

        {

            scanf("%d%d%d",&a,&b,&c);

            addedge(a,b,c);

        }

        while(d--)

        {

            scanf("%d%d%d",&a,&b,&c);

            addedge(b,a,-c);

        }

        bool flag=bellman();

        printf("Case #%d: ",t);

        if(flag)

        {

            printf("Exist!\n");

            for(i=1;i<=n;i++)

                printf("%d %d\n",dist1[i],dist2[i]);

        }

        else

            printf("Not Exist!\n");

    }

    return 0;

}

posted on 2012-09-18 21:30  sachinKung  阅读(119)  评论(0编辑  收藏  举报