​点击打开链接​

dis[2*i-1]表示第i个任务的起始时间 dis[2*i]表示第i个任务的终止时间

可得:

1 dis[2*i]-dis[2*i-1]=val[i]

2 FAS dis[2*u]-dis[2*v-1]>=1

3 FAF dis[2*u]-dis[2*v]>=1

4 SAF dis[2*u-1]-dis[2*v]>=1

5 SAS dis[2*u-1]-dis[2*v-1]>=1

建图 spfa求最长路即可

另外还要注意保证图的连通性 可以建立一个超级源点

#include <bits/stdc++.h>
using namespace std;
#define N 0x3f3f3f3f

struct node
{
int v;
int w;
int next;
};

queue <int> que;
node edge[1000010];
int first[200010],val[200010],dis[200010],book[200010],cnt[200010];
int n,m,num;

void addedge(int u,int v,int w)
{
edge[num].v=v;
edge[num].w=w;
edge[num].next=first[u];
first[u]=num++;
return;
}

void spfa()
{
int i,u,v,w,flag;
while(!que.empty()) que.pop();
for(i=1;i<=2*n;i++)
{
dis[i]=-N;
book[i]=0;
cnt[i]=0;
}
que.push(0);
dis[0]=0,book[0]=1,cnt[0]=1;
flag=1;
while(!que.empty())
{
u=que.front();
que.pop();
book[u]=0;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v,w=edge[i].w;
if(dis[v]<dis[u]+w)
{
dis[v]=dis[u]+w;
if(!book[v])
{
que.push(v);
book[v]=1,cnt[v]++;
if(cnt[v]>2*n+1)
{
flag=0;
break;
}
}
}
}
if(!flag) break;
}
if(flag)
{
for(i=1;i<=n;i++)
{
printf("%d %d\n",i,dis[2*i-1]);
}
}
else
{
printf("impossible\n");
}
return;
}

int main()
{
int cas,i,u,v,res;
char ch[10];
cas=1;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=n;i++)
{
scanf("%d",&val[i]);
addedge(2*i-1,2*i,val[i]);
addedge(2*i,2*i-1,-val[i]);
}
while(1)
{
scanf("%s",ch);
if(ch[0]=='#') break;
scanf("%d%d",&u,&v);
if(strcmp(ch,"FAS")==0) addedge(2*v-1,2*u,0);
else if(strcmp(ch,"FAF")==0) addedge(2*v,2*u,0);
else if(strcmp(ch,"SAF")==0) addedge(2*v,2*u-1,0);
else addedge(2*v-1,2*u-1,0);
}
for(i=1;i<=2*n;i+=2)
{
addedge(0,i,0);
}
printf("Case %d:\n",cas++);
spfa();
printf("\n");
}
return 0;
}