zoukankan      html  css  js  c++  java
  • POJ 3159 Candies (图论,差分约束系统,最短路)

    POJ 3159 Candies (图论,差分约束系统,最短路)

    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 A, B 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

    Http

    POJ:https://vjudge.net/problem/POJ-3159

    Source

    图论,差分约束系统,最短路径

    题目大意

    给出n个小朋友和m对小朋友A不希望小朋友B比他多c个,n比1最多能多多少糖果

    解决思路

    首先我们观察一组情况,A不希望B比他多c个,用数学语言表示就是

    [D[B]-D[a]>=c ]

    我们把式子变一下形就是

    [D[a]+c<=D[b] ]

    没错,这是不是很像最短路的形式?
    所以对于每一个A不希望B比他多c个,我们连一条边A->B,权值为c。那么若要求最后的解就求一遍最短路径就可以了。
    此题的关键是不能用spfa+queue,会超时,要用spfa+stack
    (只要题中说明了不会出现负环,就可以用spfa+stack,其效率高于spfa+queue)

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<stack>
    using namespace std;
    
    const int maxN=30001;
    const int maxM=150001;
    const int inf=2147483647;
    
    class Graph//把图的相关内容封装到Graph里,方便编写
    {
    private:
    	int cnt;
    	stack<int> S;
    	int instack[maxN];//使用stack而不是queue作为spfa的容器
    	int Head[maxN];
    	int V[maxM];
    	int W[maxM];
    	int Next[maxM];
    public:
    	int Dist[maxN];
    	void init()
    	{
    		memset(Head,-1,sizeof(Head));
    		memset(Next,-1,sizeof(Next));
    		cnt=0;
    	}
    	void Add_Edge(int u,int v,int w)
    	{
    		cnt++;
    		Next[cnt]=Head[u];
    		V[cnt]=v;
    		W[cnt]=w;
    		Head[u]=cnt;
    	}
    	void spfa()
    	{
    		memset(Dist,127,sizeof(Dist));
    		memset(instack,0,sizeof(instack));
    		while (!S.empty())
    		    S.pop();
    		Dist[1]=0;
    		instack[1]=1;
    		S.push(1);
    		do
    		{
    			int u=S.top();
    			S.pop();
    			instack[u]=0;
    			for (int i=Head[u];i!=-1;i=Next[i])
    			{
    				if (Dist[V[i]]>Dist[u]+W[i])
    				{
    					Dist[V[i]]=Dist[u]+W[i];
    					if (instack[V[i]]==0)
    					{
    						S.push(V[i]);
    						instack[V[i]]=1;
    					}
    				}
    			}
    		}
    		while (!S.empty());
    	}
    };
    
    int n,m;
    Graph G;
    
    int read();
    
    int main()
    {
    	while (cin>>n>>m)
    	{
    		G.init();
    		for (int i=1;i<=m;i++)
    		{
    			int u=read(),v=read(),w=read();
    			G.Add_Edge(u,v,w);
    		}
    		G.spfa();
    		cout<<G.Dist[n]<<endl;
    	}
    	return 0;
    }
    
    int read()
    {
    	int x=0;
    	int k=1;
    	char ch=getchar();
    	while (((ch>'9')||(ch<'0'))&&(ch!='-'))
    	    ch=getchar();
    	if (ch=='-')
    	{
    		k=-1;
    		ch=getchar();
    	}
    	while ((ch>='0')&&(ch<='9'))
    	{
    		x=x*10+ch-48;
    		ch=getchar();
    	}
    	return x*k;
    }
    
  • 相关阅读:
    个人永久性免费-Excel催化剂功能第103波-批量打开多文件或多链接
    个人永久性免费-Excel催化剂插件功能修复与更新汇总篇之八
    个人永久性免费-Excel催化剂功能第101波-批量替换功能(增加正则及高性能替换能力)
    个人永久性免费-Excel催化剂功能第99波-手机号码归属地批量查询
    个人永久性免费-Excel催化剂功能第100波-透视多行数据为多列数据结构
    个人永久性免费-Excel催化剂功能第98波-零代码零距离轻松接触并拥有金融大数据
    个人永久性免费-Excel催化剂功能第97波-快递单号批量查询物流信息
    个人永久性免费-Excel催化剂功能第95波-地图数据挖宝之IP地址转地理地址及不同经纬度版本转换
    个人永久性免费-Excel催化剂功能第96波-地图数据挖宝之全国天气查询(区域最细可到区县,最长预报4天)
    实现兼容document.querySelector的方法
  • 原文地址:https://www.cnblogs.com/SYCstudio/p/7229023.html
Copyright © 2011-2022 走看看