缩点之后按拓扑序在DAG上做一下DP。
注意SUMLEN可能会爆INT。
#include <bits/stdc++.h>
using namespace std;
map<string,int>mp;
int tot=0;
int n,m;
string s[200003];
struct edge{
int to,next;
}e[200003];
int head[200003];
int dfn[200003];
int low[200003];
int stk[200003];
bool instk[200003];
int scc[200003];
int rcnt[200003];
int len[200003];
int srcnt[200003];
int slen[200003];
int ind[200003];
vector<int>rg[200003];
int cnt,tmpdfn,scc_cnt,top;
void add(int u,int v){
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
void init(){
cnt=tmpdfn=scc_cnt=top=0;
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
}
void pro(string a){
int rc=0;
for(int i=0;a[i];i++){
if(a[i]>='A'&&a[i]<='Z')a[i]+='a'-'A';
if(a[i]=='r')rc++;
}
if(mp.find(a)==mp.end())mp[a]=++tot;
int id=mp[a];
rcnt[id]=rc;
len[id]=a.length();
}
void dfs(int u){
dfn[u]=++tmpdfn;
low[u]=dfn[u];
stk[++top]=u;
instk[u]=true;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(instk[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++scc_cnt;
srcnt[scc_cnt]=rcnt[u];
slen[scc_cnt]=len[u];
while(1){
int x=stk[top--];
instk[x]=false;
scc[x]=scc_cnt;
if(srcnt[scc_cnt]>rcnt[x]){
srcnt[scc_cnt]=rcnt[x];
slen[scc_cnt]=len[x];
}
else if(srcnt[scc_cnt]==rcnt[x]&&slen[scc_cnt]>len[x]){
slen[scc_cnt]=len[x];
}
if(x==u)break;
}
}
}
queue<int>q;
int main(){
init();
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>s[i];
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
string a,b;
cin>>a>>b;
pro(a);
pro(b);
for(int i=0;a[i];i++){
if(a[i]>='A'&&a[i]<='Z')a[i]+='a'-'A';
}
for(int i=0;b[i];i++){
if(b[i]>='A'&&b[i]<='Z')b[i]+='a'-'A';
}
int ida=mp[a],idb=mp[b];
add(ida,idb);
}
for(int i=1;i<=tot;i++){
if(!dfn[i])dfs(i);
}
for(int u=1;u<=tot;u++){
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(scc[u]==scc[v])continue;
ind[scc[u]]++;
rg[scc[v]].push_back(scc[u]);
}
}
for(int i=1;i<=scc_cnt;i++)if(ind[i]==0)q.push(i);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<rg[u].size();i++){
int v=rg[u][i];
if(srcnt[v]>srcnt[u]){
srcnt[v]=srcnt[u];
slen[v]=slen[u];
}
else if(srcnt[v]==srcnt[u]&&slen[v]>slen[u]){
slen[v]=slen[u];
}
ind[v]--;
if(ind[v]==0)q.push(v);
}
}
int sumr=0;
long long sumlen=0;
for(int i=1;i<=n;i++){
int tmpr=0,tmplen=s[i].length();
for(int j=0;s[i][j];j++){
if(s[i][j]>='A'&&s[i][j]<='Z')s[i][j]+='a'-'A';
if(s[i][j]=='r')tmpr++;
}
if(mp.find(s[i])==mp.end()){
sumr+=tmpr;
sumlen+=tmplen;
}
else {
int id=mp[s[i]];
id=scc[id];
sumr+=srcnt[id];
sumlen+=slen[id];
}
}
printf("%d %lld\n",sumr,sumlen);
}