POJ 3169 差分约束

题意:
这里写图片描述
这里写图片描述

好久没做差分约束了,,, 看到这道题第一想法是贪心…………………………

思路:
差分约束

  1. 从i到i+1的距离>=0 add(i+1,i,0)
  2. 对于互相讨厌的牛从u到v的距离>=d add(v,u,-d)
  3. 对于互相喜欢的牛从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());
}

这里写图片描述

原文地址:https://www.cnblogs.com/SiriusRen/p/6532197.html