题意:
第一行三个正整数,n,m,q,分别代表n头牛,m条信息和q条信息
接下来m行,每行三个正整数 A B D,表示A 与 B之间的距离小于等于D,接下来q行每行三个正整数 A B D,表示 A与 B之间的距离大于等于D,求1号牛--->n号牛
的最大距离
题解:
利用约束条件我们可以得:前m个条件可以得到:
A-B<=D
后q个条件可以得到:A-B>=D
变形得:B-A<=-D
,然后建边,求最短距离,即约束条件下的最大距离
AC代码:
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
//差分约束&最短路
#define inf 0x3f3f3f3f3f
const int maxn=2e5+5;
struct node
{
int v,w,nex;
}road[maxn];
int vis[maxn],dis[maxn],head[maxn],qu[maxn],num[maxn];
int n,m,cnt,q;
void input(int u,int v,int w)
{
road[cnt].v=v;
road[cnt].w=w;
road[cnt].nex=head[u];
head[u]=cnt++;
}
void spfa(int u)
{
//queue<int>q;
int iq=0;
memset(vis,0,sizeof(vis));
memset(dis,0x3f3f3f3f,sizeof(dis));
dis[u]=0;
qu[++iq]=u;
//q.push(u);
while(iq!=0)
{
int st=qu[iq];
//printf("%d\n",st);
vis[st]=0;
iq--;
num[st]++;
if(num[st]>n)//判断是否有负环产生,判断是否有点被执行了n次
{
printf("-1\n");
return;
}
//q.pop();
for(int i=head[st];~i;i=road[i].nex)
{
int v=road[i].v;
int w=road[i].w;
if(dis[v]>dis[st]+w)
{
dis[v]=dis[st]+w;
if(!vis[v])
{
vis[v]=1;
qu[++iq]=v;
}
}
}
}
if(dis[n]==0x3f3f3f3f)
printf("-2\n");
else
printf("%d\n",dis[n]);
}
int main()
{
scanf("%d %d %d",&n,&m,&q);
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
input(u,v,w);
}
for(int i=1;i<=q;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
input(v,u,-w);
}
spfa(1);
}