1. 程式人生 > >POJ 3159 Candies(差分約束系統)

POJ 3159 Candies(差分約束系統)

題目大意:給n個同學分發糖,第一行為n,m,分別代表n個學生,m個關係,
下邊的a,b,c代表b比a不能多與c個糖,即有關係b-a<=c(b<=a+c)與最短路的關係dis[b]>dis[a]+c相對,所以若求最大的差應該在滿足所有b<=a+c的條件。所以找到最小最小的b即可。

思路:本來是SPFA+手寫佇列TLE,然後看討論用棧就行- -!(手寫的時候應該是f1++,–f1)

#include<map>
#include<queue>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<stack> #include<cstring> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; const int mod=100000000; bool vis[150010]; int head[150010],cnt,dis[150010],qu[150010*4]; struct node { int to,c,next; }q[150010*4]; int n; void add(int a,int b,int c){ q[cnt].to=b; q[cnt].c=c; q[cnt]
.next=head[a]; head[a]=cnt++; } void SPFA(){ for(int i=1;i<=n;i++){ dis[i]=inf; vis[i]=false; } int f1; f1=0; //stack<int>qq; qu[f1++]=1; //qq.push(1); dis[1]=0; vis[1]=true; while(f1>0){ //int u=qq.top(); //qq.pop(); int
u=qu[--f1]; vis[u]=false; for(int i=head[u];~i;i=q[i].next){ int v=q[i].to; if(dis[v]>dis[u]+q[i].c){ dis[v]=dis[u]+q[i].c; if(!vis[v]){ vis[v]=true; //qq.push(v); qu[f1++]=v; } } } } } int main(){ int m,i,j,k; while(~scanf("%d%d",&n,&m)){ int a,b,c; cnt=0; memset(head,-1,sizeof(head)); for(i=0;i<m;++i){ scanf("%d%d%d",&a,&b,&c); add(a,b,c); } SPFA(); printf("%d\n",dis[n]); } return 0; }