• 【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;
    }
    

      

  • 相关阅读:
    bzoj 2733 [HNOI2012]永无乡
    CF550D Regular Bridge
    bzoj 1911 [Apio2010]特别行动队
    CF1137A/1138C Skyscrapers
    CF295C Greg and Friends
    CF1130E Wrong Answer
    bzoj 1029 [JSOI2007]建筑抢修
    iOS 流布局 UICollectionView使用(简单使用)
    Swift 学习笔记 (解决Swift闭包中循环引用的三种方法)
    Swift 学习笔记(面向协议编程)
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5914126.html
Copyright © 2020-2023  润新知