天天写算法之(差分约束)Schedule Problem

地址: 点击打开链接
这个题目,明确了,每个项目有每个项目之间SAS,SAF,FAF,FAS之间的关系,因此可以在他们之间进行建边。最终进行环的测试,如果形成了环说明不可行。

代码:
#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<string>  
#include<queue>  
#include<map>  
#include<cmath>  
#define INF 0x3f3f3f3f  
using namespace std;  
const int MAXN=1005;  
const int MAXM=1005;  
int v[MAXM],w[MAXM],nex[MAXM];  
int inq[MAXN],done[MAXN],dis[MAXN],first[MAXN],da[MAXN];  
int cnt;  
  
int spfa(int s,int n)  
{  
    for(int i=0;i<n;i++)dis[i]=-INF;  
    memset(inq,0,sizeof inq);  
    memset(done,0,sizeof done);  
    queue<int>q;  
    q.push(s);  
    done[s]++;  
    dis[s]=0;  
    while(!q.empty())  
    {  
        int x=q.front();q.pop();  
        inq[x]=0;  
        for(int e=first[x];~e;e=nex[e])  
        if(dis[v[e]]<dis[x]+w[e]){  
            dis[v[e]]=dis[x]+w[e];  
            if(!inq[v[e]])  
            {  
                q.push(v[e]);  
                inq[v[e]]=1;  
                if(++done[v[e]]>n)return 1;  
            }  
        }  
    }  
    return 0;  
}  
void add_(int a,int b,int c)  
{  
    v[cnt]=b;  
    w[cnt]=c;  
    nex[cnt]=first[a];  
    first[a]=cnt++;  
}  
int main()  
{  
    int n,m,i,cas=0;char cs[4];  
    while(~scanf("%d",&n)&&n)  
    {  
        int a,b;  
        memset(first,-1,sizeof first);  
        memset(nex,-1,sizeof nex);  
        cnt=0;  
        for(i=1;i<=n;i++)  
        {  
            scanf("%d",&da[i]);  
            //add_(i,n+1,da[i]);//若要求最小总时间,加上这句  
            add_(0,i,0);  
        }  
        while(~scanf("%s",cs)&&cs[0]!='#')  
        {  
            scanf("%d%d",&a,&b);  
            if(cs[0]=='F')  
            {  
                if(cs[2]=='F')add_(b,a,da[b]-da[a]);  
                else add_(b,a,-da[a]);  
            }  
            else  
            {  
                if(cs[2]=='F')add_(b,a,da[b]);  
                else add_(b,a,0);  
            }  
        }  
        printf("Case %d:\n",++cas);  
  
        if(spfa(0,n+1))printf("impossible\n");  
        else  
        {  
            for(i=1;i<=n;i++)  
                printf("%d %d\n",i,dis[i]);  
        }  
        printf("\n");  
    }  
    return 0;  
}  

猜你喜欢

转载自blog.csdn.net/qq_36616268/article/details/80612419