bzoj1179: [Apio2009]Atm scc缩点+dag上dp
先把强连通缩点,然后变成了dag,dp求终点是酒吧的最长路即可,
/**************************************************************
Problem: 1179
User: walfy
Language: C++
Result: Accepted
Time:9788 ms
Memory:77092 kb
****************************************************************/
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
const double eps=1e-6;
const int N=500000+10,maxn=100000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
vi v[N],ans[N],sv[N];
int dfn[N],low[N];
int ind,num;
int ins[N],inans[N];
int c[N],bar[N],sb[N],sc[N];
stack<int>s;
void tarjan(int u)
{
dfn[u]=low[u]=++ind;
ins[u]=2;s.push(u);
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i];
if(!dfn[x])
{
tarjan(x);
low[u]=min(low[u],low[x]);
}
else if(ins[x]==2)low[u]=min(low[u],dfn[x]);
}
if(dfn[u]==low[u])
{
num++;
while(!s.empty())
{
int x=s.top();
s.pop();
ins[x]=1;
inans[x]=num;
ans[num].pb(x);
if(x==u)break;
}
}
}
int vis[N];
void dfs(int u)
{
vis[u]=1;
for(int i=0;i<sv[u].size();i++)
{
int x=sv[u][i];
if(!vis[x])dfs(x);
sb[u]|=sb[x];
}
}
int dp[N];
int DP(int u)
{
if(dp[u]!=-1)return dp[u];
dp[u]=sc[u];
for(int i=0;i<sv[u].size();i++)
{
int x=sv[u][i];
if(sb[x])dp[u]=max(dp[u],DP(x)+sc[u]);
}
return dp[u];
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
v[a].pb(b);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
int s,p;
scanf("%d%d",&s,&p);
for(int i=0;i<p;i++)
{
int x;scanf("%d",&x);
bar[x]=1;
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<v[i].size();j++)
{
if(inans[v[i][j]]!=inans[i])
{
sv[inans[i]].pb(inans[v[i][j]]);
}
}
}
for(int i=1;i<=num;i++)
{
for(int j=0;j<ans[i].size();j++)
{
sc[i]+=c[ans[i][j]];
if(bar[ans[i][j]])sb[i]=1;
}
}
dfs(inans[s]);
// for(int i=1;i<=num;i++)
// {
// for(int j=0;j<sv[i].size();j++)
// printf("%d ",sv[i][j]);
// puts("");
// }
// for(int i=1;i<=num;i++)printf("%d %d\n",sb[i],sc[i]);
memset(dp,-1,sizeof dp);
printf("%d\n",DP(inans[s]));
return 0;
}
/********************
********************/