RE,55分,求助
查看原帖
RE,55分,求助
52243
RenaMoe楼主2020/7/28 11:42

莫名其妙的RE,数组开大到MLE还是没用

我先对于x1,y1求出所有最短路,记录每个点的pre(在最短路上的入边),通过bfs倒推出最短路的DAG,上面的每个边打上标记

再对于x2,y2同样推出最短路的DAG,从正反两个方向分别判断每个边是否在公共路径上

新建一个公共路径边的图,再拓扑dp最深链

自认为正确性和复杂度没有问题,是不是写假了啊qwq

#include <queue>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>

using namespace std;

namespace RenaMoe {

template<typename T>
inline void read(T &x) {
	x = 0; bool f = false; char in = getchar();
	while (!isdigit(in)) { if (in == '-') f = true; in = getchar(); }
	while (isdigit(in)) x = x * 10 + in - '0', in = getchar();
	x = f ? -x : x;
}

const int N = 3e3 + 9;
const int M = 6e6 + 9;
const int INF = 0x3f3f3f3f;

struct Edge {
	int nxt, to, val;
};

int n, m, x1, y1, x2, y2, cnte, ans;
int head[N], head2[N], disx1[N], disx2[N], out[N], deep[N];
// out点的度数,deep最长链的长度
Edge e[M], e_[M];// 旧、新图
bool inq[N], in1[M];// inq是否在队列里,in1边是否在x1到y1最短路上
queue<int> q;
vector<int> pre[N];

inline void add_edge(int u, int v, int w) {
	e[++cnte] = (Edge){head[u], v, w}, head[u] = cnte;
}
inline void add_edge2(int u, int v, int w) {
	e_[++cnte] = (Edge){head2[u], v, w}, head2[u] = cnte;
}

inline void SPFA(int s, int *dis) {
	for (int i = 1; i <= n; ++i) dis[i] = INF, pre[i].clear();
	dis[s] = 0;
	q.push(s), inq[s] = true;
	while (!q.empty()) {
		int u = q.front();
		q.pop(), inq[u] = false;
		for (int i = head[u], v; i; i = e[i].nxt) {
			v = e[i].to;
			if (dis[v] > dis[u] + e[i].val) {
				dis[v] = dis[u] + e[i].val;
				if (!inq[v]) q.push(v), inq[v] = true;
				pre[v].clear(), pre[v].push_back(i);
			}
			else if (dis[v] == dis[u] + e[i].val)
				pre[v].push_back(i);
		}
	}
}

inline void calc_deep() {
	memset(deep, 0, sizeof deep);
	for (int i = 1; i <= n; ++i)
		if (!out[i]) q.push(i);
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (int i = head2[u], v; i; i = e_[i].nxt) {
			v = e_[i].to, out[v]--;
			if (!out[v]) q.push(v);
			deep[v] = max(deep[v], deep[u] + e_[i].val);
		}
	}
	for (int i = 1; i <= n; ++i)
		ans = max(ans, deep[i]);
}

inline void main() {
	cnte = 1;
	read(n), read(m), read(x1), read(y1), read(x2), read(y2);
	for (int i = 1, u, v, w; i <= m; ++i)
		read(u), read(v), read(w), add_edge(u, v, w), add_edge(v, u, w);

	SPFA(x1, disx1);
	q.push(y1);
	while (!q.empty()) {
		int u = q.front();
		q.pop(), inq[u] = false;
		for (int i = 0, s = pre[u].size(); i < s; ++i) {
			int j = pre[u][i], v = e[j^1].to;
			in1[j^1] = true;
			if (!inq[v]) q.push(v), inq[v] = true;
		}
	}

	cnte = 0;
	SPFA(x2, disx2);
	q.push(y2);
	while (!q.empty()) {
		int u = q.front();
		inq[u] = false;
		q.pop();
		for (int i = 0, s = pre[u].size(); i < s; ++i) {
			int j = pre[u][i], v = e[j^1].to;
			if (in1[j])
				add_edge2(u, v, e[j].val), out[v]++;
			if (!inq[v]) q.push(v), inq[v] = true;
		}
	}
	calc_deep();

	memset(head2, 0, sizeof head2);
	cnte = 0;
	q.push(y2);
	while (!q.empty()) {
		int u = q.front();
		q.pop(), inq[u] = false;
		for (int i = 0, s = pre[u].size(); i < s; ++i) {
			int j = pre[u][i], v = e[j^1].to;
			if (in1[j^1])
				add_edge2(v, u, e[j].val), out[u]++;
			if (!inq[v]) q.push(v), inq[v] = true;
		}
	}
	calc_deep();
	printf("%d\n", ans);
}
}

int main() {
	RenaMoe::main();
	return 0;
}
2020/7/28 11:42
加载中...