Submission #1365290

#TimeUsernameProblemLanguageResultExecution timeMemory
1365290ivazivaLove Polygon (BOI18_polygon)C++20
100 / 100
162 ms32232 KiB
#include <bits/stdc++.h>

using namespace std;

#define MAXN 100001
#define int long long

int n;
vector<pair<string,string>> edges;
vector<string> kompresija;
vector<int> adj[2*MAXN];
bool pos[2*MAXN];
int idx[2*MAXN];
vector<int> toposort;
vector<vector<int>> cycles;
vector<int> graph[2*MAXN];
int dp[3][2*MAXN];
int newdp[2][2*MAXN];

void dfs(int node)
{
    pos[node]=true;
    for (int sled:adj[node])
    {
        if (!pos[sled]) dfs(sled);
    }
    toposort.push_back(node);
}

void calculate(int node,int pret)
{
    for (int sled:graph[node])
    {
        if (sled!=pret) calculate(sled,node);
    }
    int maxrazlika=-INT_MAX;
    for (int sled:graph[node])
    {
        if (sled!=pret)
        {
            dp[0][node]+=max(dp[0][sled],dp[2][sled]);
            dp[1][node]+=max(dp[0][sled],dp[2][sled]);
            dp[2][node]+=max(dp[0][sled],dp[2][sled]);
            maxrazlika=max(maxrazlika,dp[1][sled]-max(dp[0][sled],dp[2][sled]));
        }
    }
    if (maxrazlika!=-INT_MAX) dp[2][node]+=maxrazlika+1;
}

int32_t main()
{
    cin>>n;for (int i=1;i<=n;i++) {string s1,s2;cin>>s1>>s2;edges.push_back({s1,s2});kompresija.push_back(s1);kompresija.push_back(s2);}
    if (n%2==1) {cout<<-1<<endl;return 0;}
    sort(kompresija.begin(),kompresija.end());kompresija.erase(unique(kompresija.begin(),kompresija.end()),kompresija.end());
    for (pair<string,string> edge:edges)
    {
        int u=lower_bound(kompresija.begin(),kompresija.end(),edge.first)-kompresija.begin()+1;
        int v=lower_bound(kompresija.begin(),kompresija.end(),edge.second)-kompresija.begin()+1;
        adj[u].push_back(v);
    }
    for (int node=1;node<=(int)kompresija.size();node++)
    {
        if (!pos[node]) dfs(node);
    }
    reverse(toposort.begin(),toposort.end());for (int i=0;i<(int)toposort.size();i++) idx[toposort[i]]=i;
    for (int node=1;node<=(int)kompresija.size();node++) pos[node]=false;
    for (int node=1;node<=(int)kompresija.size();node++)
    {
        for (int sled:adj[node])
        {
            if (idx[node]<idx[sled]) continue;
            vector<int> cycle;cycle.push_back(node);int current=sled;pos[node]=true;
            while (current!=node) {cycle.push_back(current);pos[current]=true;current=adj[current][0];}
            cycles.push_back(cycle);
        }
    }
    for (int node=1;node<=(int)kompresija.size();node++)
    {
        for (int sled:adj[node])
        {
            if (pos[node] and pos[sled]) continue;
            graph[node].push_back(sled);graph[sled].push_back(node);
        }
    }
    int answer=0;
    for (vector<int> cycle:cycles)
    {
        for (int node:cycle) calculate(node,0);
        if ((int)cycle.size()==1) {answer+=max(dp[0][cycle[0]],dp[2][cycle[0]]);continue;}
        if ((int)cycle.size()==2) {answer+=max(2+dp[0][cycle[0]]+dp[0][cycle[1]],max(dp[0][cycle[0]],dp[2][cycle[0]])+max(dp[0][cycle[1]],dp[2][cycle[1]]));continue;}
        newdp[0][0]=max(dp[0][cycle[0]],dp[2][cycle[0]]),newdp[1][0]=-INT_MAX;
        newdp[0][1]=newdp[0][0]+max(dp[0][cycle[1]],dp[2][cycle[1]]);newdp[1][1]=1+dp[0][cycle[0]]+dp[0][cycle[1]];
        for (int pos=2;pos<(int)cycle.size();pos++)
        {
            newdp[0][pos]=max(newdp[0][pos-1],newdp[1][pos-1])+max(dp[0][cycle[pos]],dp[2][cycle[pos]]);
            newdp[1][pos]=max(newdp[0][pos-2],newdp[1][pos-2])+dp[0][cycle[pos-1]]+dp[0][cycle[pos]]+1;
        }
        int solution=max(newdp[0][(int)cycle.size()-1],newdp[1][(int)cycle.size()-1]);
        newdp[0][0]=-INT_MAX;newdp[1][0]=1+dp[0][cycle[(int)cycle.size()-1]]+dp[0][cycle[0]];
        newdp[0][1]=newdp[1][0]+max(dp[0][cycle[1]],dp[2][cycle[1]]);newdp[1][1]=-INT_MAX;
        for (int pos=2;pos+1<(int)cycle.size();pos++)
        {
            newdp[0][pos]=max(newdp[0][pos-1],newdp[1][pos-1])+max(dp[0][cycle[pos]],dp[2][cycle[pos]]);
            newdp[1][pos]=max(newdp[0][pos-2],newdp[1][pos-2])+dp[0][cycle[pos-1]]+dp[0][cycle[pos]]+1;
        }
        solution=max(solution,max(newdp[0][(int)cycle.size()-2],newdp[1][(int)cycle.size()-2]));
        answer+=solution;
    }
    cout<<n-answer<<endl;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...