题意:
好久没做差分约束了,,, 看到这道题第一想法是贪心…………………………
思路:
差分约束
- 从i到i+1的距离>=0 add(i+1,i,0)
- 对于互相讨厌的牛从u到v的距离>=d add(v,u,-d)
- 对于互相喜欢的牛从u到v的距离<=d add(u,v,d)
跑SPFA就好了
顺便判判dis 和入队次数
//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 25555
int n,ml,md,w[N],v[N],next[N],first[N],dis[N],vis[N],inq[N],tot,xx,yy,zz;
void add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
int spfa(){
queue<int>q;q.push(1),dis[1]=0;
while(!q.empty()){
int t=q.front();q.pop();
vis[t]++,inq[t]=0;
if(vis[t]>n)return -1;
for(int i=first[t];~i;i=next[i])
if(dis[v[i]]>dis[t]+w[i]){
dis[v[i]]=dis[t]+w[i];
if(!inq[v[i]])inq[v[i]]=1,q.push(v[i]);
}
}
return dis[n]>0x3ffffff?-2:dis[n];
}
int main(){
memset(first,-1,sizeof(first)),memset(dis,0x3f,sizeof(dis));
scanf("%d%d%d",&n,&ml,&md);
for(int i=1;i<=ml;i++)scanf("%d%d%d",&xx,&yy,&zz),add(xx,yy,zz);
for(int i=1;i<=md;i++)scanf("%d%d%d",&xx,&yy,&zz),add(yy,xx,-zz);
for(int i=1;i<n;i++)add(i+1,i,0);
printf("%d
",spfa());
}