关于 EVOIR2T2 旅行家
  • 板块学术版
  • 楼主optimize_2
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/10/22 21:58
  • 上次更新2023/11/4 02:47:54
查看原帖
关于 EVOIR2T2 旅行家
224978
optimize_2楼主2021/10/22 21:58

30pts.

看不出哪里错了

#include <bits/stdc++.h>
#define N 1000010
using namespace std;

struct edge {
	int v, w;
};

int n, m;
int x, y, a[N];
vector<int> u[N];

vector<int> g[N];

void addedge(int u, int v) {
	g[u].push_back(v);
	g[v].push_back(u);
}

int f[N][20];
int dif[N], v[N];
bool viss[N];
void diff(int x) {
	viss[x] = true;
	for (int i = 0; i < g[x].size(); i++) {
		if (f[x][0] == g[x][i] || viss[g[x][i]]) continue;
		diff(g[x][i]);
		dif[x] += dif[g[x][i]];
	}
}

int dep[N];
void dfs(int x, int fa) {
//	cout << fa << " -> " << x << endl;
	dep[x] = dep[fa] + 1;
	for (int i = 1; i <= dep[x]; i <<= 1) {
		f[x][i] = f[f[x][i - 1]][i - 1];
	}
	for (int i = 0; i < g[x].size(); i++) {
		if (g[x][i] == fa) continue;
		f[g[x][i]][0] = i;
		dfs(g[x][i], x);
	}
}

int lca(int x, int y) {
	if (dep[x] < dep[y]) swap(x, y);
    for (int i = 20; i >= 0; i--) {
        if (dep[f[x][i]] >= dep[y]) x = f[x][i];
        if (x == y) return x;
    }
	for (int i = 20; i >= 0; i--) {
		if (f[x][i] == f[y][i]) continue;
		else {
			x = f[x][i];
			y = f[y][i];
		}
	}
	return f[x][0];
}

bool vis[N];
int cnt, dfn[N], low[N];
int ccnt, c[N];
stack<int> s;
void tarjan(int x, int f) {
	dfn[x] = low[x] = ++cnt;
	s.push(x);
	vis[x] = true;
//	cout << "at: " << x << " nodes: " << u[x].size() << endl;
	for (int i = 0; i < u[x].size(); i++) {
		if (u[x][i] == f) continue;
//		cout << "try: " << u[x][i] << " " << dfn[u[x][i]] << " " << (!dfn[u[x][i]]) << endl; 
        if (!dfn[u[x][i]]) {
//        	cout << "fuck\n";
            tarjan(u[x][i], x);
            low[x] = min(low[x], low[u[x][i]]);
        } else if(vis[u[x][i]]) low[x] = min(low[x], dfn[u[x][i]]);
	}
//	cout << "caonima: " << x << " " << dfn[x] << " " << low[x] << " " << f << endl;
	if (dfn[x] == low[x]) {
		ccnt++;
		int top;
		while (true) {
			top = s.top();
			s.pop();
			c[top] = ccnt;
			vis[top] = false;
			v[ccnt] += a[top];
//			cout << top << " " << ccnt << " *\n";
			if (top == x) break;
		}
	}
}

int q, ans;

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
	}
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &x, &y);
		u[x].push_back(y);
		u[y].push_back(x);
//		cout << "AAEDGE"
	}
	tarjan(1, 0);
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < u[i].size(); j++) {
			int x = c[i], y = c[u[i][j]];
			if (x == y) continue;
			addedge(x, y);
		}
	}
	dfs(1, 0);
	scanf("%d", &q);
	while (q--) {
		scanf("%d%d", &x, &y);
		x = c[x];
		y = c[y];
		dif[x]++;
		dif[y]++;
		dif[lca(x, y)]--;
		dif[f[lca(x, y)][0]]--; 
	}
	diff(1);
	for (int i = 1; i <= ccnt; i++) {
		if (dif[i] > 0) {
			ans += v[i];
		}
	}
	cout << ans;
} 

或者求 hack 数据?

2021/10/22 21:58
加载中...