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

来源:互联网 发布:淘宝网旅游鞋女 编辑:程序博客网 时间:2024/04/28 18:41

 这题和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[N];int n,m,s,e,p,i,j,ne=0,top=0,t=0,scc,a[N],dfn[N],low[N],belong[N],st[N],ins[N],bar[N],dp[N],v[N];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]]);}


0 0
原创粉丝点击