Submission #956480

#TimeUsernameProblemLanguageResultExecution timeMemory
956480GrindMachineLove Polygon (BOI18_polygon)C++17
54 / 100
178 ms23404 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; typedef long long int ll; typedef long double ld; typedef pair<int,int> pii; typedef pair<ll,ll> pll; #define fastio ios_base::sync_with_stdio(false); cin.tie(NULL) #define pb push_back #define endl '\n' #define sz(a) (int)a.size() #define setbits(x) __builtin_popcountll(x) #define ff first #define ss second #define conts continue #define ceil2(x,y) ((x+y-1)/(y)) #define all(a) a.begin(), a.end() #define rall(a) a.rbegin(), a.rend() #define yes cout << "Yes" << endl #define no cout << "No" << endl #define rep(i,n) for(int i = 0; i < n; ++i) #define rep1(i,n) for(int i = 1; i <= n; ++i) #define rev(i,s,e) for(int i = s; i >= e; --i) #define trav(i,a) for(auto &i : a) template<typename T> void amin(T &a, T b) { a = min(a,b); } template<typename T> void amax(T &a, T b) { a = max(a,b); } #ifdef LOCAL #include "debug.h" #else #define debug(x) 42 #endif /* */ const int MOD = 1e9 + 7; const int N = 1e5 + 5; const int inf1 = int(1e9) + 5; const ll inf2 = ll(1e18) + 5; vector<ll> adj[N]; vector<bool> cyc(N); vector<ll> subsiz(N); ll dp[N][2]; void dfs1(ll u, ll p){ subsiz[u] = 1; trav(v,adj[u]){ if(v == p or cyc[v]) conts; dfs1(v,u); subsiz[u] += subsiz[v]; } dp[u][0] = 0, dp[u][1] = 1; ll mn = inf2; trav(v,adj[u]){ if(v == p or cyc[v]) conts; ll mnv = min(dp[v][0],dp[v][1]); dp[u][0] += mnv, dp[u][1] += mnv; ll pair_cost = dp[v][1]-1; amin(mn,-mnv+pair_cost); } dp[u][0] += mn; } void solve(int test_case) { ll n; cin >> n; map<string,ll> mp; auto get_id = [&](string s){ if(mp.count(s)) return mp[s]; return mp[s] = sz(mp)+1; }; vector<ll> indeg(n+5); vector<ll> a(n+5); rep1(i,n){ string s,t; cin >> s >> t; ll u = get_id(s), v = get_id(t); a[u] = v; adj[v].pb(u); indeg[v]++; } if(n&1){ cout << -1 << endl; return; } queue<ll> q; rep1(i,n) if(!indeg[i]) q.push(i); rep1(i,n) cyc[i] = 1; while(!q.empty()){ ll u = q.front(); q.pop(); cyc[u] = 0; ll v = a[u]; indeg[v]--; if(!indeg[v]){ q.push(v); } } vector<bool> vis(n+5); ll ans = 0; rep1(i,n){ if(vis[i] or !cyc[i]) conts; vector<int> nodes; int j = i; while(!vis[j]){ vis[j] = 1; nodes.pb(j); j = a[j]; } trav(u,nodes){ dfs1(u,-1); } ll cost = 0; if(sz(nodes) == 1){ ll u = nodes[0]; ll s = subsiz[u]; cost = min((dp[u][0]+s)/2,(dp[u][1]+s)/2); ans += cost; } else if(sz(nodes) == 2){ ll u = nodes[0], v = nodes[1]; ll su = subsiz[u], sv = subsiz[v]; ll cost = inf2; rep(j,2){ rep(k,2){ ll curr_cost = (dp[u][j]+su)/2+(dp[v][k]+sv)/2; if(j == 1 and k == 1){ curr_cost -= 2; } amin(cost,curr_cost); } } ans += cost; } else{ ll pairs = sz(nodes)/2; ans += pairs; ans += sz(nodes)&1; conts; ll best = inf2; // dont pair ends ll dp1[2], dp2[2]; memset(dp1,0x3f,sizeof dp1); memset(dp2,0x3f,sizeof dp2); dp1[0] = 0; trav(u,nodes){ ll su = subsiz[u]; rep(j,2){ rep(k,2){ ll cost = dp1[j]+(dp[u][k]+su)/2; amin(dp2[k],cost); // pair up prev and u if(j == 1 and k == 1){ amin(dp2[0],cost-1); } } } rep(j,2){ dp1[j] = dp2[j]; dp2[j] = inf2; } } amin(best,dp1[0]); amin(best,dp1[1]); // pair ends memset(dp1,0x3f,sizeof dp1); memset(dp2,0x3f,sizeof dp2); { ll u = nodes[0], v = nodes.back(); ll su = subsiz[u], sv = subsiz[v]; dp1[1] = (dp[u][1]+su)/2+(dp[v][1]+sv)/2-1; } rep1(ind,sz(nodes)-2){ ll u = nodes[ind]; ll su = subsiz[u]; rep(j,2){ rep(k,2){ ll cost = dp1[j]+(dp[u][k]+su)/2; amin(dp2[k],cost); // pair up prev and u if(j == 1 and k == 1){ amin(dp2[0],cost-1); } } } rep(j,2){ dp1[j] = dp2[j]; dp2[j] = inf2; } } amin(best,dp1[0]); amin(best,dp1[1]); ans += best; } } cout << ans << endl; } int main() { fastio; int t = 1; // cin >> t; rep1(i, t) { solve(i); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...