求助, 为啥会T掉啊
  • 板块CF786E ALT
  • 楼主wrpwrp
  • 当前回复0
  • 已保存回复0
  • 发布时间2020/9/26 22:30
  • 上次更新2023/11/5 12:32:59
查看原帖
求助, 为啥会T掉啊
139012
wrpwrp楼主2020/9/26 22:30

用线段树优化写的

#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

#define R register
const int N = 2e4 + 5;
const int inf = 0x3f3f3f3f;

inline int read() {
	int x = 0, f = 1; char a = getchar();
	for(; a > '9' || a < '0'; a = getchar()) if(a == '-') f = -1;
	for(; a >= '0' && a <= '9'; a = getchar()) x = x * 10 + a - '0';
	return x * f;
}

int n, m, S, T;
int tot;
int gtedge[N];

namespace Flow {
	struct edge {
		int to, next, f;
	}e[N * 400];
	int head[N * 6], cnt = 1;
	inline void add(int x, int y, int f) {
		//cout << x << ' ' << y << endl;
		e[++ cnt] = {y, head[x], f}; head[x] = cnt;
		e[++ cnt] = {x, head[y], 0}; head[y] = cnt;
	}
	int dep[N * 6], cur[N * 6];
	//queue<int> q;
	inline bool bfs() {
		memset(dep, 0x3f, sizeof(dep));
		//memcpy(cur, head, sizeof(cur));
		for(R int i = 1; i <= T; i ++) cur[i] = head[i];
		dep[S] = 0;
		//while(q.size()) q.pop();
		queue<int> q;
		q.push(S);
		while(q.size()) {
			int x = q.front(); q.pop();
			for(R int i = head[x]; i; i = e[i].next) {
				if(e[i].f == 0) continue;
				int y = e[i].to;
				if(dep[y] != inf) continue;
				dep[y] = dep[x] + 1;
			//	if(y == T) return 1;
				q.push(y);
			}
		}
		return dep[T] != inf;
		//return 0;
	}
	inline int dfs(int x, int T, int lim) {
		if(x == T || lim == 0) return lim;
		int tmp = 0, flow = 0;
		for(R int &i = cur[x]; i; i = e[i].next) {
			int y = e[i].to;
			if(dep[y] == dep[x] + 1 && (tmp = (dfs(y, T, min(e[i].f, lim))))) {
				e[i].f -= tmp; e[i ^ 1].f += tmp;
				flow += tmp; lim -= tmp;
				if(lim == 0) break;
			}
		}
		if(lim == 0) dep[x] = inf;
		return flow;
	}
	inline int Dinic() {
		int ans = 0;
		while(bfs()) ans += dfs(S, T, inf);
		return ans;
	}
}

namespace Seg {
	int t[N * 6], ls[N * 6], rs[N * 6];
	inline void build(int &x, int l, int r) {
		x = ++ tot;
		if(l == r) {
			Flow :: add(x, l, 1);
			gtedge[l] = x;
			return ;
		}
		int mid = (l + r) >> 1;
		build(ls[x], l, mid);
		build(rs[x], mid + 1, r);
		Flow :: add(x, ls[x], inf);
		Flow :: add(x, rs[x], inf);
	}
	inline void link(int x, int l, int r, int Le, int Ri, int nd) {
		if(Le <= l && r <= Ri) { Flow :: add(nd, x, inf); return ;}
		int mid = (l + r) >> 1;
		if(Le <= mid) link(ls[x], l, mid, Le, Ri, nd);
		if(Ri > mid) link(rs[x], mid + 1, r, Le, Ri, nd);
	}
}

namespace Tree {
	struct edge {
		int to, next;
	}e[N << 1];
	int head[N], cnt = 1;
	inline void add(int x, int y) {
		e[++ cnt] = {y, head[x]}; head[x] = cnt;
		e[++ cnt] = {x, head[y]}; head[y] = cnt;
	}
	int loc[N];
	int dep[N], fa[N], top[N], dfn[N], num, sz[N], son[N];
	inline void dfs1(int x, int fx) {
		dep[x] = dep[fx] + 1;
		fa[x] = fx;
		sz[x] = 1;
		for(R int i = head[x]; i; i = e[i].next) {
			int y = e[i].to;
			if(y == fx) continue;
			loc[y] = i / 2;
			dfs1(y, x);
			if(sz[y] > sz[son[x]]) son[x] = y;
		}
	}
	inline void dfs2(int x, int topx) {
		dfn[x] = ++ num;
		top[x] = topx;
		if(son[x]) dfs2(son[x], topx);
		for(R int i = head[x]; i; i = e[i].next) {
			int y = e[i].to;
			if(y == fa[x] || y == son[x]) continue;
			dfs2(y, y);
		}
	}
	inline void modify(int x, int y, int nd) {
		//cout << x << ' ' << y << endl;
		while(top[x] != top[y]) {
			if(dep[x] < dep[y]) swap(x, y);
			Seg :: link(Seg :: t[1], 1, n, dfn[top[x]], dfn[x], nd);
			x = fa[top[x]];// cout << "31";
		}
		if(dep[x] > dep[y]) swap(x, y);
		if(x != y) Seg :: link(Seg :: t[1], 1, n, dfn[x] + 1, dfn[y], nd);
	}
	inline void Init() {
		dfs1(1, 0);
		dfs2(1, 1);
		Seg :: build(Seg :: t[1], 1, n);
		//for(R int i = 1; i <= n; i ++) cout << top[i] << ' ' ;
	}
}

int vis[N * 6];

inline void dfs(int x) {
	vis[x] = 1;
	for(R int i = Flow :: head[x]; i; i = Flow :: e[i].next) {
		if(Flow :: e[i].f == 0) continue;
		int y = Flow :: e[i].to;
		if(vis[y] == 0) dfs(y);
	}
}

int main() {
	#ifdef IN
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	#endif
	n = read(); m = read();
	tot = n;
	for(R int i = 1; i < n; i ++) {
		int x = read(), y = read();
		Tree :: add(x, y);
	}
	
	Tree :: Init();
	S = tot + m + 1; T = tot + m + 2;
	for(R int i = 1; i <= m; i ++) {
		int x = read(), y = read();
		Tree :: modify(x, y, tot + i);
		Flow :: add(S, i + tot, 1);
	}
	//Tree :: modify(2, 3, tot + 5);
	for(R int i = 2; i <= n; i ++) Flow :: add(i, T, 1);
	
	printf("%d\n", Flow :: Dinic());
	dfs(S);
	vector <int> peo, gur;
	for(R int i = 1; i <= m; i ++)
		if(vis[i + tot] == 0) peo.push_back(i);
	for(R int i = 2; i <= n; i ++) 
		if(vis[gtedge[Tree :: dfn[i]]]) gur.push_back(Tree :: loc[i]);
	printf("%d ", (int)peo.size());
	for(R int i = 0; i < peo.size(); i ++) 
		printf("%d ", peo[i]);
	putchar('\n');
	printf("%d ", (int)gur.size());
	for(R int i = 0; i < gur.size(); i ++)
		printf("%d ", gur[i]);
	putchar('\n');
	
	return 0;
}
2020/9/26 22:30
加载中...