Submission #632809

#TimeUsernameProblemLanguageResultExecution timeMemory
632809LeticiaFCSLogičari (COCI21_logicari)C++17
110 / 110
195 ms19880 KiB
#include "bits/stdc++.h"
#define st first
#define nd second
using lint = int64_t;
constexpr int MOD = int(1e9) + 7;
constexpr int INF = 0x3f3f3f3f;
constexpr int NINF = 0xcfcfcfcf;
constexpr lint LINF = 0x3f3f3f3f3f3f3f3f;
const long double PI = acosl(-1.0);
// Returns -1 if a < b, 0 if a = b and 1 if a > b.
int cmp_double(double a, double b = 0, double eps = 1e-9) {
	return a + eps > b ? b + eps > a ? 0 : 1 : -1;
}
using namespace std;

int n;
array<array<lint,2>, 2> clear;
vector<array<array<lint,2>, 2>> dp;
vector<vector<int>> g;

int root = -1, rootColor = -1;
int pairOfRoot = -1, pairOfRootColor = -1;

const int RED = 0, BLUE = 1;

int solve(int u, int color, int parColor, int p){
    auto &DP = dp[u][color][parColor];
    if(DP != -1) return DP;
    
	DP = INF;	
	
    if (u == root && color != rootColor) return DP;
    if (u == pairOfRoot && color != pairOfRootColor) return DP;
    if (u == pairOfRoot && parColor == BLUE && rootColor == BLUE) return DP;
	
    lint sumRed = color;
    for(auto v:g[u])
        if(v != p)
        	sumRed += solve(v, RED, color, u);

    if (parColor == BLUE) return DP = min(DP, sumRed);
    if (u == root && pairOfRootColor == BLUE) return DP = min(DP, sumRed);
    if (u == pairOfRoot && rootColor == BLUE) return DP = min(DP, sumRed);
     
    for(auto v:g[u])
        if(v != p)
        	DP = min(DP, sumRed - solve(v, RED, color, u) + solve(v, BLUE, color, u) );
        	
    return DP;
}

vector<bool> visited;
void findRoot(int u, int p){
	visited[u] = true;
	for(int w: g[u])
		if(w != p){
			if(visited[w]){
				root = u;
				pairOfRoot = w;
			} else
				findRoot(w, u);		
		}
}


int main() {
	cin.tie(nullptr)->sync_with_stdio(false);
	
    cin>>n;
    g.resize(n+1);
    vector<int> degree(n+1);
    for (int i=0; i<n; i++) {
        int a, b;
        cin>>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
        degree[a]++;
        degree[b]++;
    }
    
    bool bigCycle = true;
	for (int u=1; u<=n; u++) {
		if(degree[u] != 2)
			bigCycle = false;
	}
	if(bigCycle){
		if(n % 4 == 0) cout<<n/2;
		else cout<<"-1";
		return 0;
	}
    
    visited.resize(n+1);
    findRoot(1, -1);
    
    //cout<<root<<" "<<pairOfRoot<<"\n";
    
    g[root].erase(find(g[root].begin(), g[root].end(), pairOfRoot));
	g[pairOfRoot].erase(find(g[pairOfRoot].begin(), g[pairOfRoot].end(), root));
   	
   	
    for(int i=0; i<2; i++)
    	for(int j=0; j<2; j++)
    		clear[i][j] = -1;
    		
    int ans = INF;
    {
    	dp.assign(n+1, clear);
        rootColor = RED;
        pairOfRootColor = RED;
        ans = min(ans, solve(root, rootColor, 0, pairOfRoot));
    }
    {
    	dp.assign(n+1, clear);
        rootColor = RED;
        pairOfRootColor = BLUE;
        ans = min(ans, solve(root, rootColor, 0, pairOfRoot));
    }
    {
    	dp.assign(n+1, clear);
        rootColor = BLUE;
        pairOfRootColor = RED;
        ans = min(ans, solve(root, rootColor, 0, pairOfRoot));
    }
    {
    	dp.assign(n+1, clear);
        rootColor = BLUE;
        pairOfRootColor = BLUE;
        ans = min(ans, solve(root, rootColor, 0, pairOfRoot));
    }
    
    if(ans == INF) ans = -1;
    
    cout<<ans<<"\n";
    
    return 0;
}
/*
[  ]Leu o problema certo???
[  ]Ver se precisa de long long
[  ]Viu o limite dos fors (é n? é m?)
[  ]Tamanho do vetor, será que é 2e5 em vez de 1e5??
[  ]Testar sample
[  ]Testar casos de  borda
[  ]1LL no 1LL << i
[  ]Testar mod (é 1e9+7, mesmo?, será que o mod não ficou negativo?)
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...