1. 程式人生 > >POJ 3159 Candies(spfa最短路,差分約束)

POJ 3159 Candies(spfa最短路,差分約束)

題意:幼兒園倆小朋友不和..一個編號是1,一個編號是n,給出m個關係,就是A小朋友最多比B小朋友多C個糖果,問n最多比1多多少個糖果...

n、m很大...開始我想著是求最大路,但是spfa沒法求因為這題是有環的...後來一想,直接邊權為c不就是最大了麼..求一下最短路就行了吧...因為求最大路可能對於某些條件來說產生衝突...為了保證條件的合理性,只能選擇最短路...接下來 TLE...nm範圍太大了餓..然後看人家都是用的棧...大概操作一樣,就把佇列的front改為top...就OK了...

   不懂為何...

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
#define M 1000009
#define inf 1<<30
int used[300000];
struct node
{
    int u,v,w,next;
}edge[300000];
int head[300000],t,n,m,dis[300000];
void inti()
{
    t=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
    edge[t].v=v;
    edge[t].w=w;
    edge[t].next=head[u];
    head[u]=t++;
}
int spfa()
{
    memset(used,0,sizeof(used));
    stack<int> q;
    for(int i=1;i<=n;i++)
        dis[i]=inf;
    dis[1]=0;
    used[1]=1;
    q.push(1);
    while(!q.empty())
    {
        int u=q.top();
        q.pop();
        used[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(dis[v]>dis[u]+edge[i].w)
            {
                dis[v]=dis[u]+edge[i].w;
                if(used[v]==0)
                {
                    used[v]=1;
                    q.push(v);
                }
            }
        }
    }
    return dis[n];
}
int main()
{
    while(cin>>n>>m)
    {
        inti();
        int a,b,c;
        for(int i=0;i<m;i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            add(a,b,c);
        }
        printf("%d\n",spfa());
    }
    return 0;
}