답안 #61458

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
61458 2018-07-26T04:40:18 Z ainta(#1774) Min-max tree (BOI18_minmaxtree) C++11
0 / 100
414 ms 79024 KB
#include<cstdio>
#include<algorithm>
#include<vector>
#define N_ 70100
#define SZ 131072
using namespace std;
vector<int>E[N_], Ch[N_], G[N_+N_];
int C[N_], Heavy[N_], Num[N_], cnt, Ed[N_], ppp[N_], Dep[N_], par[N_][20], INF = (1e9)+10;
int n, m, X[N_], Deg[N_+N_], Q[N_], Res[N_];
void DFS(int a, int pp) {
	C[a] = 1;
	par[a][0] = pp;
	for (int i = 0; i < 17; i++)par[a][i+1] = par[par[a][i]][i];
	for (auto &x : E[a]) {
		if (x == pp)continue;
		Dep[x] = Dep[a] + 1;
		DFS(x, a);
		Ch[a].push_back(x);
		C[a] += C[x];
	}
	int pv = 0;
	for (auto &x : Ch[a]) {
		if (C[pv] < C[x])pv = x;
	}
	Heavy[a] = pv;
}
void DFS2(int a, int pp) {
	Num[a] = ++cnt;
	ppp[a] = pp;
	if (Heavy[a])DFS2(Heavy[a], pp);
	for (auto &x : Ch[a]) {
		if (x != Heavy[a])DFS2(x, x);
	}
	Ed[a] = cnt;
}
struct point {
	int a, b, x, ck;
}w[N_];
int LCA(int a, int b) {
	if (Dep[a] < Dep[b])return LCA(b, a);
	int d = Dep[a] - Dep[b], i = 0;
	while (d) {
		if (d & 1)a = par[a][i];
		d >>= 1; i++;
	}
	for (i = 17; i >= 0; i--)if (par[a][i] != par[b][i])a = par[a][i], b = par[b][i];
	if (a != b)a = par[a][0];
	return a;
}
struct Tree {
	int Mn, Mx;
}IT[SZ+SZ];
void UDT(int nd, int Mn, int Mx) {
	IT[nd].Mn = max(IT[nd].Mn, Mn);
	IT[nd].Mx = min(IT[nd].Mx, Mx);
}
void Put(int b, int e, int Mn, int Mx) {
	b += SZ, e += SZ;
	while (b <= e) {
		if (b & 1)UDT(b, Mn, Mx);
		if (!(e & 1))UDT(e, Mn, Mx);
		b = (b + 1) >> 1, e = (e - 1) >> 1;
	}
}
void Put2(int b, int e, int x, int ck) {
	if (ck == 1) {
		Put(b, e, 0, x);
	}
	else {
		Put(b, e, x, INF);
	}
}
Tree Get(int a) {
	a += SZ;
	Tree r = { 0,INF };
	while (a) {
		r.Mn = max(r.Mn, IT[a].Mn);
		r.Mx = min(r.Mx, IT[a].Mx);
		a >>= 1;
	}
	return r;
}
void Go(int a, int pp, int x, int ck) {
	if (Dep[a] <= Dep[pp])return;
	int t = ppp[a];
	if (Dep[t] <= Dep[pp]) {
		Put2(Num[pp] + 1, Num[a], x, ck);
		return;
	}
	Put2(Num[t], Num[a], x, ck);
	Go(par[t][0], pp, x, ck);
}
int Ord(int a) {
	int t = lower_bound(X + 1, X + n + 1, a) - X;
	if (t < 1 || t > n)return 0;
	return t;
}
void Add(int a, int b) {
	G[a].push_back(b);
	G[b].push_back(a);
	Deg[a]++;
	Deg[b]++;
}

class MaxFlow {
public:
	struct Edge {
		int b, e, f;
	}E[501000];
	vector<int>G[N_+N_];
	int Level[N_ + N_], Q[N_ + N_], PV[N_ + N_], source, sink, n, flow, EC;
	void init(int N, int S, int T) {
		n = N, flow = EC = 0;
		source = S, sink = T;
	}
	void Add_Edge(int a, int b, int f) {
		G[a].push_back(EC);
		G[b].push_back(EC + 1);
		E[EC++] = { a,b,f };
		E[EC++] = { b,a,0 };
	}
	bool GetLevel() {
		int i;
		for (i = 1; i <= n; i++)Level[i] = -1;
		int head = 0, tail = 0;
		Q[++tail] = source, Level[source] = 0;
		while (head < tail) {
			int x = Q[++head];
			for (auto &y : G[x]) {
				if (E[y].f && Level[E[y].e] == -1) {
					Q[++tail] = E[y].e;
					Level[E[y].e] = Level[x] + 1;
				}
			}
		}
		return Level[sink] != -1;
	}
	int BlockFlow(int a, int f) {
		if (a == sink)return f;
		for (int &i = PV[a]; i >= 0; i--) {
			int x = G[a][i];
			if (E[x].f && Level[E[x].e] == Level[a] + 1) {
				int t = BlockFlow(E[x].e, min(f, E[x].f));
				if (t) {
					E[x].f -= t;
					E[x ^ 1].f += t;
					return t;
				}
			}
		}
		return 0;
	}
	void Dinic() {
		int t;
		while (GetLevel()) {
			for (int i = 1; i <= n; i++)PV[i] = G[i].size() - 1;
			while (t = BlockFlow(source, INF)) flow += t;
		}
	}

}G1;

int main() {
	int i, a, b;
	scanf("%d", &n);
	for (i = 1; i < SZ + SZ; i++)IT[i].Mx = INF;
	for (i = 1; i < n; i++) {
		scanf("%d%d", &a, &b);
		E[a].push_back(b);
		E[b].push_back(a);
	}
	DFS(1, 0);
	DFS2(1, 1);
	scanf("%d", &m);
	for (i = 1; i <= m; i++) {
		char pp[3];
		int x, ck;
		scanf("%s", pp);
		scanf("%d%d%d", &a, &b, &x);
		X[i] = x;
		if (pp[0] == 'M')ck = 1;
		else ck = 2;
		w[i] = { a,b,x,ck };
		int l = LCA(a, b);
		Go(a, l, x, ck);
		Go(b, l, x, ck);
	}
	sort(X + 1, X + m + 1);
	G1.init(n + m + 1, 1, n + m + 1);
	for (i = 2; i <= n; i++) {
		Tree t = Get(Num[i]);
		int b = Ord(t.Mn);
		int e = Ord(t.Mx);
		if (b)G1.Add_Edge(i, n + b, 1);
		if (e)G1.Add_Edge(i, n + e, 1);
	}
	for (i = 2; i <= n; i++) {
		G1.Add_Edge(G1.source, i, 1);
	}
	for (i = 1; i <= m; i++) {
		G1.Add_Edge(n+i, G1.sink, 1);
	}
	G1.Dinic();
	for (i = n+1; i <= n+m; i++) {
		for (auto &t : G1.G[i]) {
			if (G1.E[t].f && G1.E[t].e<=n) {
				Res[G1.E[t].e] = X[i - n];
			}
		}
	}
	for (i = 2; i <= n; i++)if (Res[i] == 0)Res[i] = 1;
	for (i = 2; i <= n; i++) {
		printf("%d %d %d\n", par[i][0], i, Res[i]);
	}
}

Compilation message

minmaxtree.cpp: In member function 'void MaxFlow::Dinic()':
minmaxtree.cpp:157:13: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    while (t = BlockFlow(source, INF)) flow += t;
           ~~^~~~~~~~~~~~~~~~~~~~~~~~
minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:165:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &n);
  ~~~~~^~~~~~~~~~
minmaxtree.cpp:168:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d", &a, &b);
   ~~~~~^~~~~~~~~~~~~~~~
minmaxtree.cpp:174:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &m);
  ~~~~~^~~~~~~~~~
minmaxtree.cpp:178:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%s", pp);
   ~~~~~^~~~~~~~~~
minmaxtree.cpp:179:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d%d", &a, &b, &x);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 12280 KB Output is correct
2 Correct 15 ms 12516 KB Output is correct
3 Incorrect 13 ms 12516 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 414 ms 79024 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 208 ms 79024 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 12280 KB Output is correct
2 Correct 15 ms 12516 KB Output is correct
3 Incorrect 13 ms 12516 KB Output isn't correct
4 Halted 0 ms 0 KB -