题目
题意: 有n头牛,有ml个关系好的牛的信息,有md个关系不好的牛的信息,对应输入的第一行的三个元素,接下来ml行,每行三个元素A,B,D,表示A牛和B牛相距不希望超过D,接下来md行,每行三个元素A,B,D表示A牛和B牛的相距至少要有D才行。求1号牛和n号牛的最大距离,如果距离无限大输出-2,如果无解输出-1。
思路: 差分约束裸题 建图跑最短路。有负环就是无解 最短路为INF 就是不受约束 。 B-A>=w 转化为 A-B<=-w B向A连边权为-w的边。
#include<cstdio>
#include<queue>
#include<cstring>
#define m(a,b) memset(a,b,sizeof a)
#define fnq freopen("input.txt","r",stdin)
using namespace std;
const int N=1e3+5,M=2e4+5,INF=0x3f3f3f3f;
struct Edge{int to,nex,len;}edge[M];int head[N],tot;
inline void add(int from,int to,int len){edge[++tot]=(Edge){to,head[from],len},head[from]=tot;}
int vis[N],out[N],dis[N];
queue<int>q;
void spfa(int n){
m(vis,0),m(out,0),m(dis,INF);
dis[1]=0,q.push(1),vis[1]=1;
int flag=0;
while(!q.empty()){
int x=q.front();q.pop(),vis[x]=0;
if((++out[x])>n) {flag=1;break;}
for(int i=head[x];i;i=edge[i].nex){
int y=edge[i].to,l=edge[i].len;
if(dis[y]>dis[x]+l){
dis[y]=dis[x]+l;
if(!vis[y]) {vis[y]=1,q.push(y);};
}
}
}
if(flag==1) {printf("-1\n");return;}
if(dis[n]==INF) {printf("-2\n");return;}
printf("%d\n",dis[n]);
}
int main(){
//fnq;
int n,m1,m2;
while(~scanf("%d%d%d",&n,&m1,&m2)){
m(head,0),tot=0;
for(int i=1,x,y,w;i<=m1;++i) scanf("%d%d%d",&x,&y,&w),add(x,y,w);
for(int i=1,x,y,w;i<=m2;++i) scanf("%d%d%d",&x,&y,&w),add(y,x,-w);
spfa(n);
}
}