제출 #120701

#제출 시각아이디문제언어결과실행 시간메모리
120701onjo0127Mergers (JOI19_mergers)C++11
100 / 100
1985 ms118748 KiB
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;

vector<int> A[500009], adj[500009];
int S[500009], in[500009], ou[500009], t, p[22][500009], np[500009], l;
int uf[500009], deg[500009];

inline bool isup(int u, int v) {return in[u] <= in[v] && ou[u] >= ou[v];}

int LCA(int u, int v) {
	if(isup(u, v)) return u;
	if(isup(v, u)) return v;
	for(int i=l; i>=0; i--) if(!isup(p[i][u], v)) u = p[i][u];
	return p[0][u];
}

void dfs(int x, int par) {
	in[x] = ++t;
	p[0][x] = np[x] = par;
	for(auto& it: adj[x]) if(it != par) dfs(it, x);
	ou[x] = ++t;
}

int root(int x) {
	if(uf[x] == x) return x;
	return uf[x] = root(uf[x]);
}

void merg(int u, int v) {
	u = root(u); v = root(v);
	uf[u] = v;
}

void mrg(int now, int anc) {
	if(isup(now, anc)) return;
	if(S[now] != S[np[now]]) merg(S[now], S[np[now]]);
	mrg(np[now], anc);
	np[now] = anc;
}

int main() {
	int N, K; scanf("%d%d",&N,&K);
	for(int i=1; i<=K; i++) uf[i] = i;
	for(int i=0; i<N-1; i++) {
		int u, v; scanf("%d%d",&u,&v);
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dfs(1, 1);
	for(int i=1; (1<<i)<=N; i++) {
		for(int j=1; j<=N; j++) p[i][j] = p[i-1][p[i-1][j]];
		l = i;
	}
	for(int i=1; i<=N; i++) {
		scanf("%d",&S[i]);
		A[S[i]].push_back(i);
	}
	vector<pii> Q;
	for(int i=1; i<=K; i++) {
		sort(A[i].begin(), A[i].end(), [&](int P, int Q) {return in[P] < in[Q];});
		for(int j=1; j<A[i].size(); j++) {
			int u = A[i][j-1], v = A[i][j];
			int lca = LCA(u, v);
			Q.push_back({u, lca});
			Q.push_back({v, lca});
		}
	}
	for(auto& it: Q) {
		int now, anc; tie(now, anc) = it;
		mrg(now, anc);
	}
	for(int i=1; i<=N; i++) {
		for(auto& it: adj[i]) {
			if(i < it) {
				int u = root(S[i]), v = root(S[it]);
				if(u != v) {
					++deg[u];
					++deg[v];
				}
			}
		}
	}
	int cnt = 0;
	for(int i=1; i<=K; i++) if(deg[i] == 1) ++cnt;
	printf("%d", (cnt+1) / 2);
	return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

mergers.cpp: In function 'int main()':
mergers.cpp:62:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int j=1; j<A[i].size(); j++) {
                ~^~~~~~~~~~~~
mergers.cpp:43:17: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  int N, K; scanf("%d%d",&N,&K);
            ~~~~~^~~~~~~~~~~~~~
mergers.cpp:46:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int u, v; scanf("%d%d",&u,&v);
             ~~~~~^~~~~~~~~~~~~~
mergers.cpp:56:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d",&S[i]);
   ~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...