Submission #293521

#TimeUsernameProblemLanguageResultExecution timeMemory
293521Aldas25Mergers (JOI19_mergers)C++14
100 / 100
1768 ms165392 KiB
//#pragma GCC optimize("O3") #include <bits/stdc++.h> //#include <ctime> using namespace std; #define FAST_IO ios_base::sync_with_stdio(0); cin.tie(nullptr) #define FOR(i, a, b) for(int i = (a); i <= (b); i++) #define REP(n) FOR(O, 1, (n)) #define pb push_back #define f first #define s second typedef long double ld; typedef long long ll; typedef pair<int, int> pii; typedef pair<int, pii> piii; typedef vector<int> vi; typedef vector<pii> vii; typedef vector<ll> vl; typedef vector<piii> viii; //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int MAXN = 500100, MAXK = 20; const ll MOD = 1e9+7; const ll INF = 1e16; const ld PI = asin(1) * 2; void setIO () { FAST_IO; } void setIO (string s) { setIO(); freopen((s+".in").c_str(),"r",stdin); freopen((s+".out").c_str(),"w",stdout); } int n, k; vi adj[MAXN]; int s[MAXN]; vi bel[MAXN]; int deg[MAXN]; int par[MAXN]; int find (int a) {return par[a] = par[a]==a ? a : find(par[a]);} bool same (int a, int b) {return find(a) == find(b);} void unite (int a, int b) { a = find(a), b = find(b); if (a == b) return; par[b] = a; } int curT = 0; vi times[MAXN]; int pr[MAXN][MAXK]; int dep[MAXN]; void dfs1 (int v, int p) { times[v].pb(++curT); FOR(i, 1,MAXK-1) pr[v][i] = pr[pr[v][i-1]][i-1]; for (int u : adj[v]) { if (u == p) continue; pr[u][0] = v; dep[u] = dep[v]+1; dfs1 (u, v); times[v].pb(++curT); } } int lca (int v, int u) { if (u == v) return u; if (dep[u] > dep[v]) swap(u,v); int d = dep[v] - dep[u]; FOR(i, 0, MAXK-1) if (d & (1<<i)) v = pr[v][i]; if (u == v) return u; for (int i = MAXK-1; i >= 0; i--) { if (pr[v][i] != pr[u][i]) { v = pr[v][i]; u = pr[u][i]; } } return pr[v][0]; } int cnt[MAXN]; void dfs3 (int v, int p) { for (int u : adj[v]) { if (u == p) continue; dfs3(u,v); cnt[v] += cnt[u]; } // cout << " v = " << v << " cnt = " << cnt[v] << endl; if (p != -1 && cnt[v] > 0) unite(v,p); } void dfs2 (int v, int p) { for (int u : adj[v]) { if (u == p) continue; dfs2(u, v); } if (p == -1) return; if (!same(v,p)) { deg[find(v)]++; deg[find(p)]++; } } vii seq; int main() { setIO(); // ifstream cin ("in.txt"); cin >> n >> k; REP(n-1) { int a, b; cin >> a >> b; adj[a].pb(b); adj[b].pb(a); } FOR(i, 1, n) cin >> s[i]; FOR(i,1 , n) bel[s[i]].pb(i); FOR(i, 1, n) par[i] = i; dfs1 (1, -1); FOR(i, 1, k) { seq.clear(); for (int v : bel[i]) for (int t : times[v]) seq.pb({t, v}); sort(seq.begin(), seq.end()); FOR(j, 0, (int)seq.size()-2) { int u = seq[j].s; int v = seq[j+1].s; cnt[u]++; cnt[v]++; cnt[lca(u,v)] -= 2; } } dfs3 (1, -1); dfs2 (1, -1); //FOR(i, 1, n) cout <<" i = " << i << " deg = " << deg[i] << endl; //FOR(i, 1, n) cout << " i = " << i << " par = " << par[i] << endl; int leaves = 0; FOR(i, 1, n) if (deg[i] == 1) leaves++; int ans = (leaves+1)/2; cout << ans <<"\n"; return 0; }

Compilation message (stderr)

mergers.cpp: In function 'void setIO(std::string)':
mergers.cpp:35:10: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   35 |   freopen((s+".in").c_str(),"r",stdin);
      |   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mergers.cpp:36:10: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   36 |   freopen((s+".out").c_str(),"w",stdout);
      |   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...