题意:给你n个字符串,你可以把字符串转换成另外的一个,需要求使得‘R’数量最小的字符串,求‘R‘最小的数量,同样数量求最小的长度;
m个转换,两个字符串 a,b;指可以单向传递;不区分大小写;
思路:有向图,环找出来,找这个环最小的’R‘,R相同,长度小;
形成无环DAG,在dfs找可以转换的最小的'R’;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> #include<bitset> #include<time.h> using namespace std; #define LL long long #define pi (4*atan(1.0)) #define eps 1e-4 #define bug(x) cout<<"bug"<<x<<endl; const int N=1e5+10,M=1e6+10,inf=1e9+7,MOD=1e9+7; const LL INF=1e18+10,mod=1e9+7; struct is { int u,v; int next; }edge[N]; int head[N]; int belong[N]; int dfn[N]; int low[N]; int stackk[N]; int instack[N]; int number[N]; int jiedge,lu,bel,top; int tot,r[N],l[N]; pair<int,int>f[N]; void update(int u,int v) { jiedge++; edge[jiedge].u=u; edge[jiedge].v=v; edge[jiedge].next=head[u]; head[u]=jiedge; } void dfs(int x) { dfn[x]=low[x]=++lu; stackk[++top]=x; instack[x]=1; for(int i=head[x];i;i=edge[i].next) { if(!dfn[edge[i].v]) { dfs(edge[i].v); low[x]=min(low[x],low[edge[i].v]); } else if(instack[edge[i].v]) low[x]=min(low[x],dfn[edge[i].v]); } if(low[x]==dfn[x]) { int sum=0; bel++; int ne,r1=inf,l1=inf; do { sum++; ne=stackk[top--]; if(r[ne]<r1) { r1=r[ne]; l1=l[ne]; } else if(r[ne]==r1) l1=min(l1,l[ne]); belong[ne]=bel; instack[ne]=0; }while(x!=ne); f[bel]=make_pair(r1,l1); number[bel]=sum; } } void tarjan() { memset(dfn,0,sizeof(dfn)); bel=lu=top=0; for(int i=1;i<=tot;i++) if(!dfn[i]) dfs(i); } vector<int> edge2[N]; int vis2[N]; void dfs2(int u,int fa) { for(int i=0;i<edge2[u].size();i++) { int v=edge2[u][i]; if(v==fa)continue; dfs2(v,u); if(f[u].first>f[v].first) f[u]=f[v]; else if(f[u].first==f[v].first&&f[u].second>f[v].second) f[u]=f[v]; } } string s[N]; map<string,int>mp; int si[N]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s[i]; int ri=0; for(int j=0;j<s[i].size();j++) { if(s[i][j]>='A'&&s[i][j]<='Z') s[i][j]=s[i][j]-'A'+'a'; if(s[i][j]=='r')ri++; } si[i]=ri; } int m; scanf("%d",&m); for(int i=1;i<=m;i++) { string a,b; cin>>a>>b; int ri=0; for(int j=0;j<a.size();j++) { if(a[j]>='A'&&a[j]<='Z') a[j]=a[j]-'A'+'a'; if(a[j]=='r')ri++; } if(mp.find(a)==mp.end())mp[a]=++tot; r[mp[a]]=ri;l[mp[a]]=a.size(); ri=0; for(int j=0;j<b.size();j++) { if(b[j]>='A'&&b[j]<='Z') b[j]=b[j]-'A'+'a'; if(b[j]=='r')ri++; } if(mp.find(b)==mp.end())mp[b]=++tot; r[mp[b]]=ri;l[mp[b]]=b.size(); update(mp[a],mp[b]); } tarjan(); memset(head,0,sizeof(head)); for(int i=1;i<=jiedge;i++) { if(belong[edge[i].u]!=belong[edge[i].v]) { edge2[belong[edge[i].u]].push_back(belong[edge[i].v]); vis2[belong[edge[i].v]]=1; } } //for(int i=1;i<=tot;i++) //cout<<belong[i]<<endl; //cout<<bel<<endl; for(int i=1;i<=bel;i++) if(!vis2[i]) dfs2(i,-1); LL ans=0,out=0; for(int i=1;i<=n;i++) { if(mp.find(s[i])==mp.end())ans+=si[i],out+=s[i].size(); else { ans+=f[belong[mp[s[i]]]].first; out+=f[belong[mp[s[i]]]].second; } } printf("%lld %lld\n",ans,out); return 0; }