题目:
分析:
用
E
[
i
]
E[i]
E[i]表示第
i
i
i个点与其它点的限制,很显然,所有点和其左边(或右边)的点没有限制,所以是
0
0
0,若两点之间的距离必须不大于
d
d
d则限制为
d
d
d,若必须不小于
t
t
t则限制为
−
t
−t
−t,这时跑一遍
S
p
f
a
Spfa
Spfa就行了
若中间出现负环,说明无法放置,若点
1
1
1和点
n
n
n之间的限制为
0
x
3
f
3
f
3
f
3
f
0x3f3f3f3f
0x3f3f3f3f说明该点没有被更新,即没有限制,输出
−
2
-2
−2
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
queue<int>q;
struct node{
int to,next,w;
}e[200001];
bool vis[100001];
int c=0,ls[200001],len[100001];
void add(int a,int b,int w)
{
e[c]=(node){b,ls[a],w};
ls[a]=c++;
return;
}
int d[100001];
int main()
{
memset(ls,-1,sizeof(ls));
memset(d,0x3f3f3f3f,sizeof(d));
int n=read(),m1=read(),m2=read();
// for(int i=2;i<=n;i++) add(i,i-1,0);
int a,b,c;
for(int i=1;i<=m1;i++)
{
a=read();b=read();c=read();
add(a,b,c);
}
for(int i=1;i<=m2;i++)
{
int a=read(),b=read();c=read();
add(b,a,-c);
}
q.push(1);d[1]=0;len[1]=1;vis[1]=true;
while(q.size())
{
int x=q.front();q.pop();vis[x]=true;
for(int i=ls[x];~i;i=e[i].next)
{
int y=e[i].to,w=e[i].w;
if(d[x]+w<d[y])
{
d[y]=d[x]+w;len[y]=len[x]+1;
if(len[y]>n) return printf("-1")&0;
if(!vis[y]) vis[y]=true,q.push(y);
}
}
vis[x]=false;
}
if(d[n]>=502345678)printf("-2");
else printf("%d",d[n]);
return 0;
}