社区讨论

求助 求大佬帮帮忙

P3627[APIO2009] 抢掠计划参与者 5已保存回复 24

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
24 条
当前快照
1 份
快照标识符
@locztnwv
此快照首次捕获于
2023/10/30 22:26
2 年前
此快照最后确认于
2023/11/05 08:45
2 年前
查看原帖
思路简单:缩点tarjantarjan+拓扑后dpdp
只WA第3,113,11
CPP
#include <stack>
#include <queue>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define reg register int
#define isdigit(x) (x <= '9'&&x >= '0')
template <typename T>
inline T Read(T Type)
{
	T x = 0,f = 1;
	char a = getchar();
	while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
	while(isdigit(a)) x = (x << 1) + (x << 3) + (a ^ '0'),a = getchar();
	return x * f;
}
const int MAXN = 5e5 + 5;
int S,pub_cnt,n,m,e_cnt,dfs_cnt,scc_cnt,fir[MAXN << 1],dp[MAXN];
struct EDGE
{
	int u,v,nxt;
	void ass(int U,int V,int NXT) {u = U,v = V,nxt = NXT;}
}edge[MAXN];
inline void addedge(int u,int v) {edge[++e_cnt].ass(u,v,fir[u]),fir[u] = e_cnt;}
struct POINT
{
	int dfn,low,scc,val;
}p[MAXN];
struct SCC
{
	int In,val;
}scc[MAXN];
stack<int> st;
bool isstack[MAXN]; 
inline void tarjan(int x)
{
	p[x].dfn = p[x].low = ++dfs_cnt,st.push(x),isstack[x] = 1;
	for(reg e = fir[x],v;e;e = edge[e].nxt)
	{
		v = edge[e].v;
		if(!p[v].dfn) tarjan(v),p[x].low = min(p[x].low,p[v].low);
		else if(isstack[v]) p[x].low = min(p[x].low,p[v].dfn);
	}
	if(p[x].dfn == p[x].low)
	{
		++scc_cnt;
		scc[scc_cnt].In = scc[scc_cnt].val = 0;
		while(1)
		{
			int t = st.top();st.pop(),isstack[t] = 0;
			p[t].scc = scc_cnt,scc[scc_cnt].val += p[t].val;
			if(x == t) break;
		}
	}
}
vector<int> seq,bh[MAXN];
inline void topo(int S)
{
	queue<int> q;
	q.push(S),dp[S] = scc[S].val;
	while(!q.empty())
	{
		int it = q.front();q.pop();
		seq.push_back(it);
		for(reg e = 0,v;(unsigned int)e < bh[it].size();e++)
		{
			v = bh[it][e],scc[v].In--;
			dp[v] = max(dp[v],dp[it] + scc[v].val);
			if(!scc[v].In) q.push(v);
		}
	}
}
int main()
{
	//freopen("P3627_3.in","r",stdin);
	n = Read(1),m = Read(1);
	for(reg i = 1;i <= m;i++)
	{
		int u = Read(1),v = Read(1);
		addedge(u,v);
	}
	for(reg i = 1;i <= n;i++) p[i].val = Read(1);
	for(reg i = 1;i <= n;i++) if(!p[i].dfn) tarjan(i);
	for(reg i = 1;i <= e_cnt;i++)
	{
		int u = p[edge[i].u].scc,v = p[edge[i].v].scc;
		if(u != v) scc[v].In++,bh[u].push_back(v);
	}
	S = Read(1),pub_cnt = Read(1);
	topo(p[S].scc);
	int ans = 0;
	for(reg i = 1;i <= pub_cnt;i++)
	{
		int op = Read(1);
		ans = max(ans,dp[p[op].scc]);
	}
	printf("%d",ans);
	return 0;
}

回复

24 条回复,欢迎继续交流。

正在加载回复...