BZOJ 1179 APIO 2009 Atm Tarjan+SPFA
2014-11-27 14:06
507 查看
题目大意:给出一张有向图,每一个节点有一个权值,经过一次之后会取走节点上的权值。有一个原点,多个汇点,问最多能收获多少权值。
思路:做一次Tarjan将图变成拓扑图,然后直接跑SPFA+Heap,比较慢,但是用了高大上的namespace,很开心。
CODE:
思路:做一次Tarjan将图变成拓扑图,然后直接跑SPFA+Heap,比较慢,但是用了高大上的namespace,很开心。
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 500000 using namespace std; struct Complex{ int pos,len; Complex(int _,int __):pos(_),len(__) {} bool operator <(const Complex &a)const { return len < a.len; } }; int points,edges,cnt; int head[MAX],total; int next[MAX],aim[MAX]; int src[MAX]; int S,T; int deep[MAX],low[MAX],_total; bool v[MAX]; int changed[MAX],sum[MAX],scc; int stack[MAX],top; bool in_stack[MAX]; namespace SPA{ int head[MAX],total; int next[MAX],aim[MAX]; int f[MAX]; inline void Add(int x,int y) { next[++total] = head[x]; aim[total] = y; head[x] = total; } int SPFA(int st,int ed) { static priority_queue<Complex> q; q.push(Complex(st,sum[st])); f[st] = sum[st]; while(!q.empty()) { Complex temp = q.top(); q.pop(); int x = temp.pos; if(f[x] > temp.len) continue; for(int i = head[x]; i; i = next[i]) if(f[aim[i]] < f[x] + sum[aim[i]]) { f[aim[i]] = f[x] + sum[aim[i]]; q.push(Complex(aim[i],f[aim[i]])); } } return f[ed]; } } inline void Add(int x,int y) { next[++total] = head[x]; aim[total] = y; head[x] = total; } void Tarjan(int x) { deep[x] = low[x] = ++_total; v[x] = true; stack[++top] = x; in_stack[x] = true; for(int i = head[x]; i; i = next[i]) { if(!v[aim[i]]) Tarjan(aim[i]),low[x] = min(low[x],low[aim[i]]); else if(in_stack[aim[i]]) low[x] = min(low[x],deep[aim[i]]); } if(low[x] == deep[x]) { ++scc; int temp; do { temp = stack[top--]; in_stack[temp] = false; sum[scc] += src[temp]; changed[temp] = scc; }while(temp != x); } } int main() { cin >> points >> edges; for(int x,y,i = 1; i <= edges; ++i) { scanf("%d%d",&x,&y); Add(x,y); } for(int i = 1; i <= points; ++i) scanf("%d",&src[i]); for(int i = 1; i <= points; ++i) if(!v[i]) Tarjan(i); for(int x = 1; x <= points; ++x) for(int i = head[x]; i; i = next[i]) if(changed[x] != changed[aim[i]]) SPA::Add(changed[x],changed[aim[i]]); cin >> S >> cnt; for(int x,i = 1; i <= cnt; ++i) { scanf("%d",&x); SPA::Add(changed[x],scc + 1); } cout << SPA::SPFA(changed[S],scc + 1) << endl; return 0; }
相关文章推荐
- 【BZOJ1179】[Apio2009]Atm (tarjan+SPFA)
- BZOJ 1179: [Apio2009]Atm(tarjan+SPFA)
- BZOJ 1179 APIO2009 ATM Tarjan+堆优化SPFA
- [bzoj1179][Apio2009]Atm Tarjan+spfa
- 【bzoj 1179】[Apio2009]Atm(Tarjan+spfa)
- 【BZOJ1179】【APIO2009】Atm(tarjan+spfa)
- [BZOJ 1179][Apio2009]Atm:Tarjan+SPFA
- bzoj1179 [Apio2009]Atm(tarjan缩点+spfa)
- 【BZOJ】1179: [Apio2009]Atm(tarjan+spfa)
- bzoj 1179: [Apio2009]Atm【tarjan+spfa】
- bzoj 1179[Apio2009]Atm (tarjan+spfa)
- BZOJ 1179: [Apio2009]Atm Tarjan强连通分量缩点,SPFA,DP
- BZOJ_1179_[Apio2009]Atm_tarjan+spfa
- [BZOJ1179] [Apio2009]Atm(tarjan缩点 + spfa)
- bzoj 1179: [Apio2009]Atm (spfa+tarjan)
- 【tarjan+SPFA】BZOJ1179-[Apio2009]Atm
- bzoj 1179 [Apio2009]Atm tarjan强联通缩点+SPFA
- BZOJ 1179: [Apio2009]Atm(tarjan缩点+spfa)
- bzoj 1179 [APIO 2009]Atm(APIO水题) - Tarjan - spfa
- [BZOJ1179][Apio2009]Atm(tarjan+spfa)