链接:点击打开链接
题意:N头牛编号1~N,其中有一些关系好的牛,它们的距离不能超过DL,还有一些关系不好的牛,它们的距离不能少于DD,给出了ML个关系好的牛的信息(AL,BL,DL)
代表牛AL和牛BL之间的最大距离DL,以及MD个关系不好的牛的信息(AD,BD,DD),问在满足这些条件的排列方式中,求1号牛和N号牛的最大距离,如果不存在这种情况输出-1,无限大输出-2
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int d[10005];
int N,ML,MD,E;
struct node{
int u,v,cost;
};
node edge[20005] ;
void bellman_ford(int s){ //因为有负边因此用bellman_ford
int i,sign;
node e;
for(i=0;i<=N;i++)
d[i]=INF;
d[s]=0;
while(1){
sign=0;
for(i=0;i<E;i++){
e=edge[i];
if(d[e.u]!=INF&&d[e.v]>d[e.u]+e.cost){
sign=1;
d[e.v]=d[e.u]+e.cost;
}
}
if(!sign)
break;
}
}
bool find_negative_loop(){
int i,j;
node e;
memset(d,0,sizeof(d));
for(i=0;i<N;i++)
for(j=0;j<E;j++){
e=edge[j];
if(d[e.v]>d[e.u]+e.cost){
d[e.v]=d[e.u]+e.cost;
if(i==N-1)
return 1;
}
}
return 0;
} //判断有无负环
int main(){ //因为d[AL]+DL≥d[BL];d[BD]-DD>=d[AD];所以将DD看作一条
int i; //BD到AD的负边,问题就变为求1到N的最短路
while(scanf("%d%d%d",&N,&ML,&MD)!=EOF){
E=ML+MD;
for(i=0;i<ML;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].cost);
for(i=0;i<MD;i++){
scanf("%d%d%d",&edge[i+ML].v,&edge[i+ML].u,&edge[i+ML].cost);
edge[i+ML].cost*=-1;
}
if(find_negative_loop()){ //有负环则无解
printf("-1\n");
continue;
}
bellman_ford(1);
if(d[N]==INF)
printf("-2\n");
else
printf("%d\n",d[N]);
}
return 0;
}