蒟蒻 TLE on #3 求助
查看原帖
蒟蒻 TLE on #3 求助
361432
Froranzen楼主2021/3/18 00:42

RT,求助大佬


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;

inline char nc () {static char buf[1 << 21], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread (buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}

inline int read () { 
    register int x(0),f(1); char ch = getchar (); 
    while (ch > '9' || ch < '0') {if (ch == '-') f = ~f +1; ch = getchar ();} 
    while (ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar ();} 
    return x * f;
}

int n, m, p;

struct Node {
	int from, to, next;
}e[1000005];

int cnt, head[500005];

inline void add (int u, int v) {
	e[++cnt] = (Node) {u, v, head[u]};
	head[u] = cnt;
}

int dfn[500005], low[500005], val[500005], color[500005];
bool vis[500005];
int w[500005];
int tot, color_tot;
int st[500005], stack;

inline void update (int u) {
	w[color_tot] += val[u];
	color[u] = color_tot;
	vis[u] = 0;
	stack--;
}

inline void tarjan (int u) {
	dfn[u] = low[u] = ++tot;
	vis[u] = 1;
	st[++stack] = u;
	for (register int i(head[u]); i; i = e[i].next) {
		int v = e[i].to;
		if (!dfn[v]) {
			tarjan (v);
			low[u] = min (low[u], low[v]);
		}
		else if (vis[v]) low[u] = min (low[u], dfn[v]);
	}
	if (low[u] == dfn[u]) {
		color_tot++;
		while (st[stack] != u) {
			int tmp = st[stack];
			update (tmp);
		}
		update (u);
	}
}

struct node {
	int to, next;
}qwq[1000003];

int cnt_edge, head_edge[500003];

void add_edge (int u, int v) {
	qwq[++cnt_edge] = (node) {v, head_edge[u]};
	head_edge[u] = cnt_edge;
}

struct edge {
	int l, r;
	int maxs, maxv;
}root[2000003];

inline void push_up (int p) {
	if (root[p<<1].maxs > root[p<<1|1].maxs) root[p].maxs = root[p<<1].maxs, root[p].maxv = root[p<<1].maxv;
	else root[p].maxs = root[p<<1|1].maxs, root[p].maxv = root[p<<1|1].maxv;
}

inline void build (int p, int l, int r) {
	root[p].l = l, root[p].r = r;
	if (l == r) {
		root[p].maxs = -1;
		root[p].maxv = l;
		return ;
	}
	int mid = l + r >> 1;
	build (p<<1, l, mid);
	build (p<<1|1, mid+1, r);
	push_up (p);
}

inline void modfiy (int p, int l, int w) {
	if (root[p].l == root[p].r) {
		root[p].maxs = w;
		return ;
	}
	int mid = root[p].l + root[p].r >> 1;
	if (l <= mid) modfiy (p<<1, l, w);
	else modfiy (p<<1|1, l, w);
	push_up (p);
}

int dis[500005];

void dijkstra (int s) {
	build (1, 1, color_tot);
	modfiy (1, s, w[s]);
	memset (dis, -1, sizeof (dis));
	dis[s] = w[s];
	while (root[1].maxs != -1) {
		int u = root[1].maxv;
		modfiy (1, u, -1);
		for (register int i(head_edge[u]); i; i = qwq[i].next) {
			int v = qwq[i].to;
			if (dis[v] < dis[u] + w[v]) {
				dis[v] = dis[u] + w[v];
				modfiy (1, v, dis[v]);
			}
		}
	}
}

int s, ans;

int main () {
	//freopen ("D:/浏览器下载/P3627_3.in", "r", stdin); 
	n = read (), m = read ();
	for (register int i(1); i <= m; ++i) {
		int u = read (), v = read ();
		add (u, v);
	}
	for (register int i(1); i <= n; ++i) val[i] = read ();
	for (register int i(1); i <= n; ++i) {
		if (!dfn[i]) tarjan (i);
	}
	for (register int i(1); i <= m; ++i) {
		int u = e[i].from, v = e[i].to;
		if (color[u] ^ color[v]) {
			add_edge (color[u], color[v]);
		}
	}
	s = read (), p = read ();
	dijkstra (color[s]);
	while (p--) {
		int o = read ();
		ans = ans > dis[color[o]] ? ans : dis[color[o]];
	}
	printf("%d\n", ans);
}
2021/3/18 00:42
加载中...