Submission #1057046

#TimeUsernameProblemLanguageResultExecution timeMemory
1057046RiverFlowLogičari (COCI21_logicari)C++14
110 / 110
41 ms31296 KiB
#include <bits/stdc++.h> #define nl "\n" #define no "NO" #define yes "YES" #define fi first #define se second #define vec vector #define task "main" #define _mp make_pair #define ii pair<int, int> #define sz(x) (int)x.size() #define all(x) x.begin(), x.end() #define evoid(val) return void(std::cout << val) #define FOR(i, a, b) for(int i = (a); i <= (b); ++i) #define FOD(i, b, a) for(int i = (b); i >= (a); --i) #define unq(x) sort(all(x)); x.resize(unique(all(x)) - x.begin()) using namespace std; template<typename U, typename V> bool maxi(U &a, V b) { if (a < b) { a = b; return 1; } return 0; } template<typename U, typename V> bool mini(U &a, V b) { if (a > b or a == -1) { a = b; return 1; } return 0; } const int N = (int)2e5 + 9; const int mod = (int)1e9 + 7; void prepare(); void main_code(); int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); if (fopen(task".inp", "r")) { freopen(task".inp", "r", stdin); freopen(task".out", "w", stdout); } const bool MULTITEST = 0; prepare(); int num_test = 1; if (MULTITEST) cin >> num_test; while (num_test--) { main_code(); } } void prepare() {}; stack<int> st; bool vis[N]; vector<int> cyc, g[N]; bool on[N]; void dfs(int u, int p) { st.push(u); vis[u] = 1; on[u] = 1; for(int v : g[u]) if (v ^ p) { if (vis[v] == 0) { dfs(v, u); } else if (on[v]) { // (u->v) canh nguoc // cerr << u << ' ' << v << nl; while (sz(st)){ int u = st.top(); st.pop(); on[u]=0; cyc.push_back(u); if (u == v) break ; } return ; } } if (sz(st)) st.pop(), on[u]=0; } long long dp[N][2][2], s[2][2]; const int INF = (int)1e8; const bool DEBUG = 0; void dfs2(int u, int p) { vector<int> child; for(int v : g[u]) if (v != p and !on[v]) { dfs2(v, u); child.push_back(v); } if (sz(child) == 0) { dp[u][0][0] = 0; dp[u][0][1] = 1; return ; } // dp(i, j : dinh i da thoa man chua, k : dinh i co phai la blue khong) FOR(i, 0, 1) FOR(j, 0, 1) s[i][j] = 0; for(int v : child) { FOR(i, 0, 1) FOR(j, 0, 1) s[i][j] += dp[v][i][j]; } dp[u][0][0] = s[1][0]; for(int v : child) { dp[u][1][0] = min(dp[u][1][0], dp[v][1][1] + s[1][0] - dp[v][1][0]); } dp[u][0][1] = s[0][0] + 1; for(int v : child) { dp[u][1][1] = min(dp[u][1][1], dp[v][0][1] + s[0][0] - dp[v][0][0] + 1); } if (DEBUG) { cout << "u: " << u << nl; FOR(i, 0, 1) FOR(j, 0, 1) cout << i << ' ' << j << ' ' << dp[u][i][j] << nl; } } bool saf(int a, int b, int c, int d) { if ( (a & d) or (b & c) ) return 0; return 1; } long long f[N][2][2]; void main_code() { int n; cin >> n; for(int i = 1; i <= n; ++i) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } FOR(i, 1, n) FOR(j, 0, 1) FOR(k, 0, 1) dp[i][j][k] = INF; dfs(1, 0); FOR(i, 1, n) on[i]=0; for(int x : cyc) on[x] = 1; for(int x : cyc) { dfs2(x, 0); } if (DEBUG) {cout<<"cyc: ";for(int x : cyc) cout << x << ' '; cout << nl;} long long ans = INT_MAX; memset(f, -1, sizeof f); int m = sz(cyc); FOR(ia, 0, 1) FOR(ja, 0, 1) FOR(ib, 0, 1) FOR(jb, 0, 1) if (saf(ia, ja, ib, jb) and dp[cyc[0]][ia][ja] < INF and dp[cyc.back()][ib][jb] < INF) { // (ia, ja) state ta chon cho 1 // (ib, jb) state ta chon cho m - 1 f[0][ia][ja] = dp[cyc[0]][ia][ja]; // if (ia!=0 or ja!=0 or ib!=0 or jb!=0) continue; if (DEBUG) { cout << "state: "; cout << ia << ' ' << ja << ' ' << ib << ' ' << jb << nl; } FOR(t, 0, m - 2) FOR(i, 0, 1) FOR(j, 0, 1) if (f[t][i][j] != -1 and f[t][i][j] < INF) { if (DEBUG) { cout << t << ' ' << i << ' ' << j << ' ' << f[t][i][j] << nl; } if (t == 0) { FOR(u, 0, 1) FOR(v, 0, 1) { if ( (ia or jb) and v ) continue ; if ( !(ia or jb or v) ) continue ; if ( j and u ) continue ; mini(f[t + 1][u or ja][v], f[t][i][j] + dp[cyc[t + 1]][u][v]); } } else if (t == m - 2) { for(int check=1;check>0;--check) { if ( (ja or ib) and j ) continue ; if ( !(ja or ib or j)) continue ; if ( !(i or jb) ) continue ; if (i and jb) continue ; mini(f[t + 1][1][jb], f[t][i][j] + dp[cyc[t + 1]][ib][jb]); } } else { FOR(u, 0, 1) FOR(v, 0, 1) { if ( i and v ) continue ; if ( !(i or v) ) continue ; if (j and u) continue ; // cerr << t << ' ' << i << ' ' << j << ' ' << u << ' ' << v << ' ' << dp[cyc[t+1]][u][v] << nl; mini(f[t + 1][u or j][v], f[t][i][j] + dp[cyc[t + 1]][u][v]); } } f[t][i][j] = -1; } if (f[m - 1][1][jb] != -1) { if (DEBUG) { cout << "valid - state: "; cout << ia << ' ' << ja << ' ' << ib << ' ' << jb << nl; } ans = min(ans, f[m - 1][1][jb]); } FOR(i, 0, 1) FOR(j, 0, 1) f[m - 1][i][j] = -1; } if (ans > n) ans = -1; cout << ans; } /* Let the river flows naturally */

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:36:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   36 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:37:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   37 |         freopen(task".out", "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...