手造的数据全过了,随机数据错了 10 个:
#include<bits/stdc++.h>
#define ll long long
#define mxn 200003
#define md 1000000007
#define pb push_back
#define mkp make_pair
#define ld long double
#define umap unordered_map
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
#define pq priority_queue
using namespace std;
int n,m,tot,t,cnt,ans,nx[680],id[680][680],gr[680],st[680],ct[680],dfn[680],low[680];
char s[5];
vector<int>g[680];
bool v[680],ins[680],b[680][680],e[680][680];
void dfs(int x){
dfn[x]=low[x]=++tot,st[++t]=x,ins[x]=1;
for(int i:g[x]){
if(!dfn[i]){
dfs(i);
low[x]=min(low[x],low[i]);
}else if(ins[i])low[x]=min(low[x],dfn[i]);
}
if(low[x]==dfn[x]){
int y;m++;
do{
y=st[t--],ins[y]=0;
gr[y]=m;
}while(y!=x);
}
}
bool ds(int x){
rep(i,1,cnt)if(e[x][i]&&!v[i]){
v[i]=1;
if(nx[i]==-1||ds(nx[i])){
nx[i]=x;
return 1;
}
}
return 0;
}
int solve(){
int ans=0;
memset(nx,-1,sizeof(nx));
rep(i,1,cnt){
memset(v,0,sizeof(v));
if(ds(i))ans++;
}
return ans;
}
signed main(){
scanf("%d",&n);
rep(i,1,n){
scanf("%s",s);
g[s[0]-'A'+1].pb(s[1]-'A'+1);
}
rep(i,1,26)if(!dfn[i])dfs(i);
rep(i,1,26)for(int j:g[i])b[gr[i]][gr[j]]=1;
rep(i,1,m)rep(j,1,m)if(i!=j&&b[i][j]){
ct[i]++,ct[j]++;
// cout<<i<<" "<<j<<'\n';
id[i][j]=++cnt;
}
// cout<<">"<<m<<'\n';
rep(i,1,m)rep(j,1,m)if(i!=j&&b[i][j])
rep(k,1,m)if(j!=k&&b[j][k]){
e[id[i][j]][id[j][k]]=1;
}
rep(k,1,cnt)rep(i,1,cnt)rep(j,1,cnt)if(e[i][k]&&e[k][j])e[i][j]=1;
ans=cnt-solve();
rep(i,1,m)if(!ct[i]&&b[i][i])ans++;
cout<<ans;
return 0;
}