题意:给你n,ml,md。接下来ml行,代表两头牛之间必学在某距离内,接下来md行,代表两头牛必须距离至少某距离远,问1到n最远可以多远。无解输出-1,可以无限远输出-2,否则输出距离。
思路:差分约束,构完图直接spfa,有环则是-1的情况,如果1到n构完图无路径则是-2,不然可以求得最大值。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 1<<30
using namespace std;
int fst[1005],next[30005],node[30005],l[30005],en;
int n,ml,md;
int cnt[1005];
int dis[1005];
bool inq[1005];
void init()
{
en=0;
memset(fst,-1,sizeof(fst));
memset(cnt,0,sizeof(cnt));
memset(inq,0,sizeof(inq));
}
void add(int u,int v,int len)
{
next[en]=fst[u];
fst[u]=en;
node[en]=v;
l[en]=len;
en++;
}
int spfa()
{
for(int i=1;i<=n;i++)dis[i]=maxn;
queue<int>q;
dis[1]=0;
q.push(1);
inq[1]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
inq[u]=0;
for(int i=fst[u];i!=-1;i=next[i])
{
int v=node[i];
if(dis[v]>dis[u]+l[i])
{
dis[v]=dis[u]+l[i];
if(!inq[v])
{
q.push(v);
inq[v]=1;
cnt[v]++;
if(cnt[v]>n)
{
return -1;
}
}
}
}
}
if(dis[n]==maxn)return -2;
return dis[n];
}
int main()
{
int u,v,len;
while(scanf("%d%d%d",&n,&ml,&md)!=EOF)
{
init();
for(int i=0;i<ml;i++)
{
scanf("%d%d%d",&u,&v,&len);
add(u,v,len);
}
for(int i=0;i<md;i++)
{
scanf("%d%d%d",&u,&v,&len);
add(v,u,-len);
}
cout<<spfa()<<endl;
}
return 0;
}