记录编号 |
342086 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[APIO2009] 抢掠计划 |
最终得分 |
100 |
用户昵称 |
sxysxy |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.739 s |
提交时间 |
2016-11-08 09:08:30 |
内存使用 |
0.30 MiB |
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 500001
class Graph
{
vector<int> G[MAX];
vector<int> GS[MAX];
vector<int> sccp[MAX];
int low[MAX];
int dfn[MAX];
int w[MAX];
int stk[MAX];
int scc[MAX];
int sccw[MAX];
bool is_fin[MAX];
bool scc_fin[MAX];
int scc_cnt;
int stktop;
int time_stamp;
int n;
int s;
public:
Graph(int n_nodes)
{
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(scc, 0, sizeof(scc));
memset(is_fin, false, sizeof(is_fin));
memset(sccw, 0, sizeof(sccw));
time_stamp = 1;
stktop = 0;
scc_cnt = 0;
n = n_nodes;
}
inline void addedge(int u, int v)
{
G[u].push_back(v);
}
void tarjan(int u)
{
dfn[u] = low[u] = ++time_stamp;
stk[stktop++] = u;
for(int i = 0; i < G[u].size(); i++)
{
int to = G[u][i];
if(!dfn[to])
{
tarjan(to);
low[u] = min(low[u], low[to]);
}else if(!scc[to])
{
low[u] = min(low[u], dfn[to]);
}
}
if(low[u] == dfn[u])
{
int x;
scc_cnt++;
while(true)
{
x = stk[--stktop];
sccp[scc_cnt].push_back(x);
scc[x] = scc_cnt;
sccw[scc_cnt] += w[x];
if(is_fin[x])scc_fin[scc_cnt] = true;
if(x == u || !stktop)break;
}
}
}
void make_GS()
{
for(int i = 1; i <= n; i++)
if(!dfn[i])tarjan(i);
for(int i = 1; i <= scc_cnt; i++)
{
for(int j = 0; j < sccp[i].size(); j++)
{
int u = sccp[i][j];
for(int k = 0; k < G[u].size(); k++)
{
int t = G[u][k];
if(scc[t] != i)
GS[i].push_back(scc[t]);
}
}
}
}
int ans;
bool vis[MAX];
int dist[MAX];
void spfa()
{
int sp = scc[s];
dist[sp] = sccw[sp];
queue<int> q;
q.push(sp);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 0; i < GS[u].size(); i++)
{
int to = GS[u][i];
if(dist[to] < dist[u]+sccw[to])
{
dist[to] = sccw[to]+dist[u];
if(!vis[to])
{
q.push(to);
vis[to] = true;
}
}
}
vis[u] = false;
}
for(int i = 1; i <= scc_cnt; i++)
if(scc_fin[i])ans = max(ans, dist[i]);
}
void result()
{
ans = 0;
memset(vis, false, sizeof(vis));
memset(dist, 0, sizeof(dist));
spfa();
printf("%d\n", ans);
}
inline void set_s(int st)
{
s = st;
}
inline void input_w()
{
for(int i = 1; i <= n; i++)
scanf("%d", w+i);
}
inline void input_p(int p)
{
for(int i = 1; i <= p; i++)
{
int x;
scanf("%d", &x);
is_fin[x] = true;
}
}
};
int main()
{
freopen("atm.in", "r", stdin);
freopen("atm.out", "w", stdout);
int n, m;
scanf("%d %d", &n, &m);
Graph *g = new Graph(n);
for(int i = 0; i < m; i++)
{
int a, b;
scanf("%d %d", &a, &b);
g->addedge(a, b);
}
g->input_w();
int s, p;
scanf("%d %d", &s, &p);
g->set_s(s);
g->input_p(p);
g->make_GS();
g->result();
delete g;
return 0;
}