POJ 3159 Candies 還是差分約束(棧的SPFA)
阿新 • • 發佈:2019-02-01
題目大意:
n個小朋友分糖果,你要滿足他們的要求(a b x 意思為b不能超過a x個糖果)並且編號1和n的糖果差距要最大。
思路:
嗯,我先揭發一下,1號是分糖果的孩子,班長大人!(公報私仇啊。。。,欺負N號的小朋友~ 好吧,我開玩笑的)
嗯,這題要求最短路徑。為啥是最短?你以前都在玩最長呀~
因為這題要求的是最大的。圖的三角不等式有:d[v]- d[u]<=w(u,v); d[v]<=d[u]+w(u,v); 即而鬆弛的條件為: if(d[v]>d[u]+w(u,v)) d[v]=d[u]+w(u,v); 通過不斷的鬆弛,使得d的值不斷變小,直到滿足所有條件,也就是說滿足條件的時候就是最大的了~
建立圖,b - a <=x 然後就是spfa了,不過這題竟然卡隊列了。。看discuss人家用stack,然後我也改了,就這樣過了。。。。。。
還有這題不能建立超級源點。
設第i個小孩子分到的糖果為s[i],那麼 有s[i]>=0
而上面的是b-a<=x,由於這題求的是最短路徑,所以要改為小於號也就是 -s[i]<=0,然後如果新增一個點比如說0那麼就是應該從i到0了,那麼就無用了。。。。
#include<cstdio> #include<cstring> #include<stack> using namespace std; const int MAXN=30000+10; const int MAXM=350000; const int INF=-999999; int n,m,head[MAXN],len,dis[MAXN]; bool vis[MAXN]; struct edge { int to,val,next; }e[MAXM]; void add(int from,int to,int val) { e[len].to=to; e[len].val=val; e[len].next=head[from]; head[from]=len++; } void spfa() { int s=1; stack<int> q; q.push(s); vis[s]=true; dis[s]=0; while(!q.empty()) { int cur=q.top(); q.pop(); vis[cur]=false; for(int i=head[cur];i!=-1;i=e[i].next) { int id=e[i].to; if(dis[id] > dis[cur] + e[i].val) { dis[id]=dis[cur]+e[i].val; if(!vis[id]) { q.push(id); vis[id]=true; } } } } } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) { head[i]=-1; dis[i]=-INF; vis[i]=false; } len=0; for(int i=0;i<m;i++) { int from,to,val; scanf("%d%d%d",&from,&to,&val); add(from,to,val); } spfa(); printf("%d\n",dis[n]); } return 0; }