The main topic: give a graph, each node has a weight, after a time will take away the weights on the node. There is one origin, multiple sinks, and how many weights can be harvested.
Idea: do a Tarjan map into a topological map, and then run directly spfa+heap, relatively slow, but with a tall namespace, very happy.
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define MAX 500000using namespace std; struct complex{int pos,len; Complex (int _,int __):p OS (_), 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] &Gt 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;}
Bzoj 1179 Apio Atm TARJAN+SPFA