Puzzle: Bare pinch point + shortest path (DP)
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue >using namespace Std;const int maxn=500009;const int oo=1000000000;int n,m;int v[maxn];int cntedge;int head[maxn];int To[maxn<<1],nex[maxn<<1];void addedge (int x,int y) {nex[++cntedge]=head[x];to[cntedge]=y;head[x]= Cntedge;} Vector<int>g[maxn];int dfsclock,scccnt;int pre[maxn],lowlink[maxn],sccno[maxn];int S[maxn],top;void Dfs (int u ) {Pre[u]=lowlink[u]=++dfsclock; s[++top]=u;for (int i=0;i<g[u].size (); ++i) {int v=g[u][i];if (!pre[v]) {Dfs (v); Lowlink[u]=min (lowlink[u],lowlink[ V]);} else if (!sccno[v]) {lowlink[u]=min (lowlink[u],pre[v]);}} if (Lowlink[u]==pre[u]) {++scccnt;for (;;) {int x=s[top--];sccno[x]=scccnt;if (x==u) Break;}}} int isb[maxn];int w[maxn];void Tarjan () {for (int i=1;i<=n;++i) {if (!pre[i]) Dfs (i);} for (int i=1;i<=n;++i) w[sccno[i]]+=v[i];for (int u=1;u<=n;++u) {for (int i=0;i<g[u].size (); ++i) {int v=g[u][i] ; if (Sccno[u]!=sccno[v]) Addedge (Sccno[u],sccno[v]);}}}int s;queue<int>q;int inq[maxn];int d[maxn];void SPFA () {for (int i=1;i<=scccnt;++i) {d[i]=-oo;inq[i]=0;} D[s]=w[s];inq[s]=1;q.push (s), while (!q.empty ()) {int X=q.front (); Q.pop (); inq[x]=0;for (int i=head[x];i;i=nex[i]) {if (D[x]+w[to[i]]>d[to[i]]) {d[to[i]]=d[x]+w[to[i]];if (!inq[to[i]]) {Inq[to[i]]=1;q.push (to[i]);}}}} int main () {scanf ("%d%d", &n,&m), while (m--) {int x,y;scanf ("%d%d", &x,&y); G[x].push_back (y);} for (int i=1;i<=n;++i) scanf ("%d", &v[i]); Tarjan (); scanf ("%d%d", &s,&m), while (m--) {int x;scanf ("%d", &x); isb[sccno[x]]=1;} S=sccno[s]; SPFA (); int ans=-oo;for (int i=1;i<=scccnt;++i) {if (Isb[i]) Ans=max (Ans,d[i]);} printf ("%d\n", ans); return 0;}
Bzoj 1179 [APIO2009]ATM