您的位置:首页 > 其它

[BZOJ1179]APIO2009 ATM |强联通分量|DP

2015-04-18 09:45 513 查看
这题和1093差不多,也就是缩环之后spfa/拓扑排序/记忆化搜索搞一下,多注意一点的就是一个点有酒吧的时候它才能向前更新答案。。
#include<cstdio>
#include<iostream>
#include<memory.h>
#define N 1000005
#define clr(a) memset(a,0,sizeof(a))
using namespace std;
struct edge
{
int e,next;
}ed
;
int n,m,s,e,p,i,j,ne=0,top=0,t=0,scc,a
,dfn
,low
,belong
,st
,ins
,bar
,dp
,v
;
void add(int s,int e)
{
ed[++ne].e=e;ed[ne].next=a[s];
a[s]=ne;
}
void tarjan(int x)
{
dfn[x]=low[x]=++t;
ins[x]=1;st[++top]=x;
int to;
for (int j=a[x];j;j=ed[j].next)
if (!dfn[to=ed[j].e]) tarjan(to),low[x]=min(low[x],low[to]);
else if (ins[to]) low[x]=min(low[x],dfn[to]);
if (dfn[x]==low[x])
{
++scc;
while (st[top+1]!=x)
{
belong[st[top--]]=scc;
v[scc]+=v[st[top+1]];
ins[st[top+1]]=0;
if (bar[st[top+1]]) bar[scc]=1;
}
}
}
void dfs(int x)
{
dfn[x]=1;
int to;
if (bar[x]) dp[x]=v[x];else dp[x]=0;
for (int j=a[x];j;j=ed[j].next)
{
if (!dfn[to=ed[j].e]) dfs(to);
if (dp[to]) dp[x]=max(dp[x],dp[to]+v[x]);
}
}
int main()
{
freopen("1179.in","r",stdin);
scanf("%d%d",&n,&m);
clr(a);clr(v);
for (i=1;i<=m;i++)
{
scanf("%d%d",&s,&e);
add(s,e);
}
for (i=1;i<=n;i++) scanf("%d",&v[i]);
scanf("%d%d",&s,&p);
clr(bar);
for(i=1;i<=p;i++)
{
scanf("%d",&e);
bar[e]=1;
}
clr(dfn);clr(low);clr(ins);clr(belong);scc=n;
tarjan(s);
for (i=1;i<=n;i++)
for (j=a[i];j;j=ed[j].next)
if (belong[i]&&belong[ed[j].e]&&belong[i]!=belong[ed[j].e]) add(belong[i],belong[ed[j].e]);
dfs(belong[s]);
printf("%d\n",dp[belong[s]]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: