poj3159 Candies(差分约束)

传送门

题目大意 

n个人分糖果 其中i要求j不能比他的糖果数多c个 求第一个人的糖果数与第n个人的糖果数差最大

题解

由题目可知

cnt[j]-cnt[i]≤c 变形--cnt[j]≤cnt[[i]+c

这个式子像是单源最短路问题上的松弛操作...

因为c是大于等于0的 不会出现负环 在没有负环的

图上spfa的栈实现是比队列实现效率高的(涨姿势..

而且spfa的dfs判环是比bfs判环效率高的,上题可知(玄学

然后建图 跑spfa 图不连通无解

代码

#include<iostream>
#include<stack>
#include<cstdio>
#include<cstring>
#define mxn 30003
#define mxe 150009
using namespace std;

int n,m,a,b,c,sumedge;
int head[mxn],vis[mxn],dis[mxn];

struct Edge{
    int x,y,z,nxt;
    Edge(int x=0,int y=0,int z=0,int nxt=0):
        x(x),y(y),z(z),nxt(nxt){}
}edge[mxe];

void add(int x,int y,int z){
    edge[++sumedge]=Edge(x,y,z,head[x]);
    head[x]=sumedge;
}

void spfa(){
    dis[1]=0;stack<int>q;
    q.push(1);
    while(q.size()){
        int now=q.top();q.pop();vis[now]=0;
        for(int i=head[now];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(dis[v]>dis[now]+edge[i].z){
                dis[v]=dis[now]+edge[i].z;
                if(vis[v]==0){vis[v]=1;q.push(v);}
            }
        }
    }
}

int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(vis,0,sizeof(vis));
        memset(head,0,sizeof(head));
        memset(dis,0x3f,sizeof(dis));
        sumedge=0;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        spfa();
        printf("%d
",dis[n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zzyh/p/7389779.html