zoukankan      html  css  js  c++  java
  • poj 3159 Candies

    这题目做的一个纠结啊。

    N个人份糖果,其中含有约束条件,即对于a,b,c有 b-a<=c,看到这个不等式马上感觉到要用最短路解决了,问Sn-S1的最大值是多少,我们令S1=0即求Sn的最大值,查分约束题目,
    求最短路,初始原点1到2,3,..,n的距离为INF,每次松弛找到第一组满足约束条件的解,这个解就是最大值,但是这个题目有问题啊,用最常用的bellman_ford无法通过啊,n,m值太大了,只能用spfa或者其他的优化方法,这个题用spfa+stack,用queue也会超时的,我猜想可能stack的访问效率较后者快吧,我最开始用的dijkstra+优先队列,不是超时就是WA,WA的时候我真搞不明白为什么,感觉很简单的题目怎么回WA呢,郁闷死了。。下面附上spfa+stack的代码吧。刚明白为什么我刚才用di。。为何错误了,由于一个节点可以多次如队列,这样由于入队列的仅仅是一个简单的int,无法区分,我们只需定义一个结构体包含节点号及当前len即可,两种方法都a了,。。

    #include <iostream>
    #include <queue>
    #include <stack>
    #include <stdio.h>
    using namespace std;
    const int N=150002;
    const int INF=10000000;
    struct node{
        int to,next,weight;
    };
    node edge[N];
    int num,n,m,dist[30002],adj[30002];
    struct cmp
    {
        bool operator() (const int &a, const int &b)
        {
            return dist[a] > dist[b];
        }
    };
    void dijkstra(int s)
    {
        int u,i,v,w;
        bool visit[30002];
        for(i=0;i<=n;i++)
        {
            dist[i]=INF;
            visit[i]=false;
        }
        dist[s]=0;
        int Stack[30002],top=0;
        Stack[top++]=s;
        visit[s]=true;
        while(top)
        {
            u=Stack[--top];
            visit[u]=false;
            for(i=adj[u];i!=-1;i=edge[i].next)
            {
            //    cout<<dist[u]<<" "<<edge[i].weight<<" "<<dist[edge[i].to]<<endl;
                v=edge[i].to;
                w=edge[i].weight;
                if(dist[v]>dist[u]+w)
                {
                    dist[v]=dist[u]+w;
                    if(!visit[v])
                    {
                        Stack[top++]=v;
                        visit[v]=true;
                    }
                }
            }
        }
        printf("%d\n",dist[n]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int i,a,b,w;
        num=0;
        for(i=0;i<=n;i++)
            adj[i]=-1;
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&w);
            edge[num].to=b;
            edge[num].weight=w;
            edge[num].next=adj[a];
            adj[a]=num++;
        }
        dijkstra(1);
        return 0;
    }

    下面的是dijkstra+优先队列,只贴核心:

        priority_queue<qNode> q;
        qNode tmp,newNode;
        tmp.x=s;
        tmp.d=0;
        q.push(tmp);
        while(!q.empty())
        {
            tmp=q.top();q.pop();
            u=tmp.x;
            if(visit[u])
                continue;
            visit[u]=true;
            if(u == n)
                break;
            for(i=adj[u];i!=-1;i=edge[i].next)
            {
            //    cout<<dist[u]<<" "<<edge[i].weight<<" "<<dist[edge[i].to]<<endl;
                v=edge[i].to;
                w=edge[i].weight;
                if(!visit[v] && dist[v]>dist[u]+w)
                {
                    dist[v]=dist[u]+w;
                    newNode.x=v;
                    newNode.d=dist[v];
                    q.push(newNode);
                }
            }
        }

  • 相关阅读:
    Linux基础命令—clear
    Linux基础命令—mv
    Linux基础命令—rm
    Linux基础命令—cp
    Linux基础命令—touch
    Linux基础命令—tree
    C#获取设备话筒主峰值(实时音频输出分贝量)
    C# 获取基类或者接口的所有继承类方法
    RegisterAttached 两种绑定方式
    RijndaelManaged 加密
  • 原文地址:https://www.cnblogs.com/buptLizer/p/2173407.html
Copyright © 2011-2022 走看看