【poj3159】 Candies

http://poj.org/problem?id=3159 (题目链接)

题意

  有n个小朋友,班长要给每个小朋友发糖果。m种限制条件,小朋友A不允许小朋友B比自己多C个糖果。问第n个小朋友最多比第1个小朋友多多少糖果。

Solution 

  原来这就是所谓的差分约束。。浅显易懂的博客超详细的博客。 

  总结一下: 

  >=,求最小值,做最长路; 

  <=,求最大值,做最短路。 

  可能会觉得很奇怪,用线性规划的角度解释吧。其实我们需要求的就是(n)-(1)<=x或者(n)-(1)>=x,要保证满足所有的约束的话,我们需要求出最小(大)的x。所以就用最短路求出<=情况的最小x,用最长路求出>=情况的最大x。 

  还有就是有最短路负环(最长路正环)的话说明无解。答案为inf(-inf)时为任意解。 

代码

// poj3159
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 2147483640
#define MOD 998244353
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
    int f,x=0;char ch=getchar();
    while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();}
    while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

const int maxn=30010,maxm=150010;
struct edge {int to,next,w;}e[maxm];
struct data {
    int x,num;
    friend bool operator < (const data &a,const data &b) {
        return a.x>b.x;
    }
};
int dis[maxn],vis[maxn],head[maxn],cnt,n,m;
priority_queue<data> q;

void insert(int u,int v,int w) {
    e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
}
void Dijkstra() {
    data x,y;
    x.x=0;x.num=1;
    for (int i=1;i<=n;i++) dis[i]=inf;
    dis[1]=0;
    q.push(x);
    while (q.size()) {
        x=q.top();q.pop();
        if (vis[x.num]) continue;
        vis[x.num]=1;
        for (int i=head[x.num];i;i=e[i].next)
            if (e[i].w+x.x<dis[e[i].to] && !vis[e[i].to]) {
                y.num=e[i].to;
                dis[e[i].to]=y.x=e[i].w+x.x;
                q.push(y);
            }
    }
}
int main() {
    scanf("%d%d",&n,&m);
    for (int u,v,w,i=1;i<=m;i++) {
        scanf("%d%d%d",&u,&v,&w);
        insert(u,v,w);
    }
    Dijkstra();
    printf("%d",dis[n]);
    return 0;
}

  

posted @ 2016-09-27 20:08  MashiroSky  阅读(397)  评论(0编辑  收藏  举报