POJ 3169 差分约束 spfa写法

建模的时候考虑最短路 最长路问题,此题两种情况都包含,我们把最长路转化为最短路

 输出的时候判断 解的存在性(三种情况)

/**
喜欢dis[j]-dis[i]<=len(最短路)
不喜欢d[j]-d[i]>=len(最长路)-->优化d[i]-d[j]<=-len(最短路)
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<queue>
using namespace std;
const int maxe=150010;
const int maxv=30010;
const int INF=0x3f3f3f3f;
int head[maxv],cnt,dis[maxv];
struct Edge {
    int to,val,next;
} edge[maxe];
struct Node {
    int u,dis;
    bool operator< (const Node rhs) const {
        return this->dis>rhs.dis;
    }
} now,temp;
void init() {
    memset(head,-1,sizeof head);
    cnt=0;
}
void addedge(int from,int to,int val) {
    edge[cnt].to=to;
    edge[cnt].val=val;
    edge[cnt].next=head[from];
    head[from]=cnt++;
}
bool spfa(int s,int n) {//常规queue写法
    queue<int> q;
    bool inq[maxv];
    int visit[maxv];
    for(int i=1; i<=n; i++)
        dis[i]=INF,inq[i]=false,visit[i]=0;
    dis[s]=0,q.push(s),inq[s]=true;
    while(!q.empty()) {
        int temp=q.front();
        q.pop();
        inq[temp]=false;
        for(int i=head[temp]; i!=-1; i=edge[i].next) {
            if(dis[edge[i].to]>dis[temp]+edge[i].val) {
                dis[edge[i].to]=dis[temp]+edge[i].val;
                if(!inq[edge[i].to]) {
                    if(++visit[edge[i].to]>=n)
                        return false;//dis[edge[i].to]=-INF;如果允许负权回路,就不要return
                    if(visit[edge[i].to]<=n)
                        q.push(edge[i].to);
                    inq[edge[i].to]=true;
                }
            }
        }
    }
    return true;
}

int main(void) {
#ifndef ONLINE_JUDGE
    freopen("E:\\input.txt","r",stdin);
#endif // ONLINE_JUDGE
    int n,m1,m2;
    scanf("%d%d%d",&n,&m1,&m2);
    init();
    int A,B,C;
    while(m1--) {
        scanf("%d%d%d",&A,&B,&C);
        addedge(A,B,C);
    }
    while(m2--) {
        scanf("%d%d%d",&A,&B,&C);
        addedge(B,A,-C);
    }
    if(spfa(1,n)) {
        if(dis[n]==INF)
            printf("-2\n");
        else
            printf("%d\n",dis[n]);
    }
    else printf("-1\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shadandeajian/article/details/81324775
今日推荐