码迷,mamicode.com
首页 > Windows程序 > 详细

luogu P3627 [APIO2009]抢掠计划

时间:2020-05-09 01:21:05      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:stream   set   cst   algo   stack   ons   namespace   dex   计划   

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>

using namespace std;

const int N=500009;
stack <int> s;
queue <int> q;
int head[N],cnt,n,m,LOW[N],DFN[N],sum[N],bar[N],belong[N],S,P,money[N],ans,Bar[N];
int Index,SCC,ins[N],x[N],y[N],f[N],deg[N];
struct Edge
{
	int nxt,to;
}g[N];

void add(int from,int to)
{
	g[++cnt].nxt=head[from];
	g[cnt].to=to;
	head[from]=cnt;
}

int read()
{
	int x=0;
	char c=getchar();
	while(c<‘0‘||c>‘9‘)
		c=getchar();
	while(c>=‘0‘&&c<=‘9‘)
		x=x*10+c-‘0‘,c=getchar();
	return x;
}

void init()
{
	n=read(),m=read();
	for (int i=1;i<=m;i++)
	{
		x[i]=read(),y[i]=read();
		add(x[i],y[i]);
	}
	for (int i=1;i<=n;i++)
		money[i]=read();
}

void Tarjan(int x)
{
	LOW[x]=DFN[x]=++Index;
	s.push(x),ins[x]=1;
	for (int i=head[x];i;i=g[i].nxt)
	{
		int v=g[i].to;
		if(!DFN[v])
		{
			Tarjan(v);
			LOW[x]=min(LOW[x],LOW[v]);
		}
		else if(ins[v])
			LOW[x]=min(LOW[x],DFN[v]);
	}
	if(LOW[x]==DFN[x])
	{
		int v;SCC++;
		do
		{
			v=s.top();
			belong[v]=SCC,ins[v]=0,sum[SCC]+=money[v];
			s.pop();
		}while(v!=x);
	}
}

void dfs(int x,int Money)
{
	printf("%d\n",x);
	if(bar[x])
		ans=max(ans,Money);
	for (int i=head[x];i;i=g[i].nxt)
	{
		int v=g[i].to;
		dfs(v,Money+sum[v]);
	}
}

void TP_sort()
{
	for (int i=1;i<=SCC;i++)
		if(!deg[i]&&i!=belong[S])
			q.push(i);
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for (int i=head[x];i;i=g[i].nxt)
		{
			int v=g[i].to;
			deg[v]--;
			if(deg[v]==0&&v!=belong[S])
				q.push(v);
		}
	}
	q.push(belong[S]);
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for (int i=head[x];i;i=g[i].nxt)
		{
			int v=g[i].to;
			f[v]=max(f[v],f[x]+sum[v]);
			if(!--deg[v])
				q.push(v);
		}
	}
}

void work()
{
	for (int i=1;i<=n;i++)
		if(!DFN[i])
			Tarjan(i);
	S=read(),P=read();
	memset(head,0,sizeof(head)),cnt=0;
	for (int i=1;i<=m;i++)
		if(belong[x[i]]!=belong[y[i]])
			add(belong[x[i]],belong[y[i]]),deg[belong[y[i]]]++;
	for (int i=1;i<=P;i++)
	{
		int x;
		x=read();bar[belong[x]]=1;
	}
	TP_sort();
	for (int i=1;i<=SCC;i++)
		if(bar[i])
			ans=max(ans,f[i]);
	printf("%d\n",ans+sum[belong[S]]);
}

int main()
{
	init();
	work();
	return 0;
}

luogu P3627 [APIO2009]抢掠计划

标签:stream   set   cst   algo   stack   ons   namespace   dex   计划   

原文地址:https://www.cnblogs.com/With-penguin/p/12853992.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!