【poj3159】 Candies

http://poj.org/problem?id=3159 (題目鏈接)

題意:有n個小朋友,班長要給每個小朋友發糖果。m種限制條件,小朋友A不允許小朋友B比自己多C個糖果。問第1個小朋友最多比第n個小朋友多多少糖果。

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 Dijistra() {
    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);
    }
    Dijistra();
    printf("%d",dis[n]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章