This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define int ll
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define rng(i,c,n) for(int i=c;i<n;i++)
#define fi first
#define se second
#define pb push_back
#define sz(a) (int)a.size()
#define vec(...) vector<__VA_ARGS__>
#define _3NRqilq ios::sync_with_stdio(0),cin.tie(0)
typedef long long ll;
using pii=pair<int,int>;
using vi=vector<int>;
void print(){cout<<'\n';}
template<class h,class...t>
void print(const h&v,const t&...u){cout<<v<<' ',print(u...);}
#define all(a) a.begin(),a.end()
#define nare {cout<<"-1\n";exit(0);}
const int inf=1e9;
signed main(){
_3NRqilq;
int m;
cin>>m;
vec(pair<string,string>) _es;
vec(string) tmp;
rep(i,m){
string s,t;
cin>>s>>t;
tmp.pb(s);
tmp.pb(t);
_es.pb({s,t});
}
sort(all(tmp));
tmp.erase(unique(all(tmp)),tmp.end());
int n=sz(tmp);
if(n%2){
nare;
}
vec(vi) adj(n),radj(n);
rep(i,m){
auto [s,t]=_es[i];
int u=lower_bound(all(tmp),s)-tmp.begin();
int v=lower_bound(all(tmp),t)-tmp.begin();
adj[u].pb(v);
radj[v].pb(u);
}
vi usd(n);
vi way,cyc;
vi incyc(n);
vec(vi) dp(n,vi(2));
vi edp(n);
auto fout_cycle=[&]()->int{
auto dfs=[&](auto self,int v)->void{
usd[v]=1;
dp[v][0]+=1;
int now=0,mi=0;
for(auto u:radj[v]){
if(incyc[u]) continue;
self(self,u);
now+=dp[u][0];
mi=min(mi,-dp[u][0]+dp[u][1]);
}
dp[v][0]+=now+mi;
dp[v][1]=now;
};
for(auto v:cyc){
incyc[v]=1;
}
for(auto v:cyc){
dfs(dfs,v);
}
for(auto v:cyc){
edp[v]=0; // dp(v,0) but is disconnected from child
for(auto u:radj[v]){
if(incyc[u]) continue;
edp[v]+=dp[u][0];
}
}
int res=0;
if(sz(cyc)==1){
res=dp[cyc.back()][0];
}else{
int s=cyc[0];
int t=cyc.back();
if(sz(cyc)==2){
res=min(dp[s][1]+dp[t][1],dp[s][0]+dp[t][0]);
}else{
// (s,t) are connected
{
vi fdp(2,inf);
rep(i,sz(cyc)-1){
int v=cyc[i];
vi gdp(2,inf);
if(!i){
gdp[0]=edp[v]+1;
gdp[1]=inf;
}else{
// last was 1
gdp[0]=min(gdp[0],fdp[1]+edp[v]+1);
// last was 0
gdp[0]=min(gdp[0],fdp[0]+dp[v][0]);
gdp[1]=min(gdp[1],fdp[0]+dp[v][1]);
}
fdp=gdp;
}
res=dp[t][1]+fdp[0];
}
// (s,t) are disconnected
{
vi fdp(2,inf);
rep(i,sz(cyc)){
int v=cyc[i];
vi gdp(2,inf);
if(!i){
gdp[0]=dp[v][0];
gdp[1]=dp[v][1];
}else{
// last was 1
gdp[0]=min(gdp[0],fdp[1]+edp[v]+1);
// last was 0
gdp[0]=min(gdp[0],fdp[0]+dp[v][0]);
gdp[1]=min(gdp[1],fdp[0]+dp[v][1]);
}
fdp=gdp;
}
res=min(res,fdp[0]);
}
}
}
return res;
};
// just find one cycle
auto dfs=[&](auto self,int v)->void{
usd[v]=1;
way.pb(v);
for(auto u:adj[v]){
if(usd[u]){
if(!sz(cyc)){
per(i,sz(way)){
cyc.pb(way[i]);
if(way[i]==u) break;
}
reverse(all(cyc));
}
return;
}
if(!usd[u]){
self(self,u);
}
}
way.pop_back();
};
int ans=0;
rep(rt,n){
if(usd[rt]) continue;
way.clear();
cyc.clear();
dfs(dfs,rt);
ans+=fout_cycle();
}
print(ans);
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |