zoukankan      html  css  js  c++  java
  • poj3159

    Candies
    Time Limit: 1500MS   Memory Limit: 131072K
    Total Submissions: 28133   Accepted: 7766

    Description

    During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher brought the kids of flymouse’s class a large bag of candies and had flymouse distribute them. All the kids loved candies very much and often compared the numbers of candies they got with others. A kid A could had the idea that though it might be the case that another kid B was better than him in some aspect and therefore had a reason for deserving more candies than he did, he should never get a certain number of candies fewer than B did no matter how many candies he actually got, otherwise he would feel dissatisfied and go to the head-teacher to complain about flymouse’s biased distribution.

    snoopy shared class with flymouse at that time. flymouse always compared the number of his candies with that of snoopy’s. He wanted to make the difference between the numbers as large as possible while keeping every kid satisfied. Now he had just got another bag of candies from the head-teacher, what was the largest difference he could make out of it?

    Input

    The input contains a single test cases. The test cases starts with a line with two integers N and M not exceeding 30 000 and 150 000 respectively. N is the number of kids in the class and the kids were numbered 1 through N. snoopy and flymouse were always numbered 1 and N. Then follow M lines each holding three integers AB and c in order, meaning that kid A believed that kid B should never get over c candies more than he did.

    Output

    Output one line with only the largest difference desired. The difference is guaranteed to be finite.

    Sample Input

    2 2
    1 2 5
    2 1 4

    Sample Output

    5

    Hint

    32-bit signed integer type is capable of doing all arithmetic.

    Source

    题解:

    题意:班上有n个同学,现在有一些糖要分给他们,设第i个同学得到的糖为p[i],分糖必须满足条件:第i个同学要求第j个同学的糖不能超过自己k个,即p[j] - p[i] <= k,k >= 0。要求在满足这些条件的情况下,求出p[n] - p[1]的最大值。

    分析:由p[j] - p[i] <= k可得p[j] <= p[i] + k

    在单源最短路径的算法中有一步是“若mindis[j] > mindis[i] + dis[i][j],则mindis[j] = mindis[i] + dis[i][j],这样就满足mindis[j] <= mindis[i] + dis[i][j]”。因此本题可以使用单源最短路径的算法来解决,对于“第i个同学要求第j个同学的糖不能超过自己k个,即p[j] - p[i] <= k,k >= 0”这个条件,建立一条边(i->j)=k,由于不含负权路径,因此建立完所有边之后以第1个同学为起点,可以利用Spfa+Stack算法求解,但由于数据原因必须用Stack,如果用Queue则会超时。

    Pass:

    一直不知道差分约束是什么类型题目,最近在写最短路问题就顺带看了下,原来就是给出一些形如x-y<=b不等式的约束,问你是否满足有解的问题

    好神奇的是这类问题竟然可以转换成图论里的最短路径问题,下面开始详细介绍下

    比如给出三个不等式,b-a<=k1,c-b<=k2,c-a<=k3,求出c-a的最大值,我们可以把a,b,c转换成三个点,k1,k2,k3是边上的权,如图

    由题我们可以得知,这个有向图中,由题b-a<=k1,c-b<=k2,得出c-a<=k1+k2,因此比较k1+k2和k3的大小,求出最小的就是c-a的最大值了

    根据以上的解法,我们可能会猜到求解过程实际就是求从a到c的最短路径,没错的....简单的说就是从a到c沿着某条路径后把所有权值和k求出就是c -a<=k的一个

    推广的不等式约束,既然这样,满足题目的肯定是最小的k,也就是从a到c最短距离...

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    #define N 150010
    int d[N],u[N],v[N],head[N],next[N],stack[N*4],vis[N];
    int n,m,S,T,x,y,z,tot=0;
    inline void bianbao(int x,int y,int z){
        u[++tot]=y;
        v[tot]=z;
        next[tot]=head[x];
        head[x]=tot;
    }
    inline void spfa(){
        for(int i=2;i<=n;i++) d[i]=0x3f3f3f3f; 
        d[S=1]=0;
        int top=0;
        stack[++top]=S;
        vis[S]=1;
        while(top){
            int p=stack[top--];
            vis[p]=0;
            for(int i=head[p];i;i=next[i])
                if(d[u[i]]>d[p]+v[i]){
                    d[u[i]]=d[p]+v[i];
                    if(!vis[u[i]]){
                        vis[u[i]]=1;
                        stack[++top]=u[i];
                    }
                }
        }
        printf("%d
    ",d[n]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            bianbao(x,y,z);
        }
        spfa();
        return 0;
    }
  • 相关阅读:
    python之matplotlib库中pyplot的基本使用(python数据分析之绘制图形)
    小球称重问题~通过三次称重找出十二个小球质量不一样的小球,并判断小球轻重
    python爬虫—爬取英文名以及正则表达式的介绍
    Python爬取酷狗飙升榜前十首(100)首,写入CSV文件
    Requests库主要方法解析以及Requests库入门需要掌握的框架
    彻底理解Java中的21种锁!
    JavaIO流常见面试题
    Linux常用命令
    语言学习网
    类加载器的命名空间
  • 原文地址:https://www.cnblogs.com/shenben/p/5618619.html
Copyright © 2011-2022 走看看