题目大意:
FJ有n头奶牛,有ml头奶牛互相喜欢,它们之间的距离不能超过di,有md头奶牛互相讨厌,它们之间的距离不能少于di。
输入:
第一行:3个数,n,ml,md。
第2~ml+1行:一共ml行,每一行包含三个数a,b,d,表示互相喜欢的奶牛。
第ml+2~ml+md+1行:一共md行,每一行包含三个数a,b,d,表示互相讨厌的奶牛。
输出:
共一行,一个数,输出奶牛1到奶牛n的距离,如果不满足限制条件,输出-1;若它们之间的距离可以无限大,则输出-2。
分析:
一个裸的差分约束+SPFA,代码实现也很简单,不懂的自己看代码。
code:
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 1000
#define MAXM 10000
using namespace std;
struct node{
int to,next,val;
}adj[2*MAXM+5];
int n,ml,md;
int dis[MAXN+5]//用来保存每头牛到第一头牛的距离;
int head[MAXN+5],cnt;
int vis[MAXN+5]//用来记录每一个点访问的次数;
bool inq[MAXN+5]//用来记录点是否在队列里;
void add(int u,int v,int d)
{
adj[++cnt].to=v;
adj[cnt].val=d;
adj[cnt].next=head[u];
head[u]=cnt;
}
void SPFA()//用来判断是否有负权环路
{
queue<int>q;
int i;
memset(vis,false,sizeof vis);
memset(inq,false,sizeof inq);
memset(dis,0x01010101,sizeof dis);
dis[1]=0;
++vis[1];
inq[1]=true;
q.push(1);
while(!q.empty())
{
int u=q.front();
inq[u]=false;
q.pop();
for(i=head[u];i;i=adj[i].next)
{
int v=adj[i].to,w=adj[i].val;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!inq[v])
{
++vis[v];
if(vis[v]>n)
{
printf("-1");//有负权环路
return;
}
inq[v]=true;
q.push(v);
}
}
}
}
printf("%d",(dis[n]==(int)0x01010101)?-2:dis[n]);//牛1与牛n没有连通
}
int main()
{
int i;
int s,t,d;
scanf("%d%d%d",&n,&ml,&md);
for(i=1;i<=ml;i++)
{
scanf("%d%d%d",&s,&t,&d);
add(s,t,d);
}
for(i=1;i<=md;i++)
{
scanf("%d%d%d",&s,&t,&d);
add(t,s,-d);
}
SPFA();
}