一开始还想拆个点建图,后来发现直接把边权+d就可以了,最后记得判一判最长路。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define inf 1000000000
#define maxn 1010
using namespace std;
int head[maxn],next[maxn],to[maxn],len[maxn],dis[maxn],q[maxn],cnt[maxn];
bool vis[maxn],flag;
int n,m1,num,s,d,m2;
void addedge(int x,int y,int z)
{
num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num;
}
void spfa()
{
for (int i=1;i<=n;i++) dis[i]=-inf;
dis[s]=d;
int l=0,r=1;
q[1]=s;vis[s]=1;
while (l!=r)
{
l++;if (l==maxn) l=0;
int x=q[l];cnt[x]++;
for (int p=head[x];p;p=next[p])
if (dis[x]+len[p]>dis[to[p]])
{
dis[to[p]]=dis[x]+len[p];
if (!vis[to[p]])
{
if (cnt[to[p]]==n) {flag=1;return;}
r++;if (r==maxn) r=0;
q[r]=to[p];vis[to[p]]=1;
}
}
vis[x]=0;
}
}
int main()
{
scanf("%d%d%d%d%d",&d,&m1,&n,&m2,&s);
for (int i=1;i<=m1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y,d);
}
for (int i=1;i<=m2;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,d-z);
}
spfa();
if (flag) printf("-1\n");
else
{
int mx=-inf;
for (int i=1;i<=n;i++) mx=max(mx,dis[i]);
printf("%d\n",mx);
}
return 0;
}