社区讨论
求助 求大佬帮帮忙
P3627[APIO2009] 抢掠计划参与者 5已保存回复 24
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 24 条
- 当前快照
- 1 份
- 快照标识符
- @locztnwv
- 此快照首次捕获于
- 2023/10/30 22:26 2 年前
- 此快照最后确认于
- 2023/11/05 08:45 2 年前
思路简单:缩点+拓扑后
只WA第点
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 条回复,欢迎继续交流。
正在加载回复...