[CF467D] Fedor and Essay

After you had helped Fedor to find friends in the «Call of Soldiers 3» game, he stopped studying completely. Today, the English teacher told him to prepare an essay. Fedor didn't want to prepare the essay, so he asked Alex for help. Alex came to help and wrote the essay for Fedor. But Fedor didn't like the essay at all. Now Fedor is going to change the essay using the synonym dictionary of the English language.

Fedor does not want to change the meaning of the essay. So the only change he would do: change a word from essay to one of its synonyms, basing on a replacement rule from the dictionary. Fedor may perform this operation any number of times.

As a result, Fedor wants to get an essay which contains as little letters «R» (the case doesn't matter) as possible. If there are multiple essays with minimum number of «R»s he wants to get the one with minimum length (length of essay is the sum of the lengths of all the words in it). Help Fedor get the required essay.

Please note that in this problem the case of letters doesn't matter. For example, if the synonym dictionary says that word cat can be replaced with word DOG, then it is allowed to replace the word Cat with the word doG.

Input

The first line contains a single integer m (1 ≤ m ≤ 105) — the number of words in the initial essay. The second line contains words of the essay. The words are separated by a single space. It is guaranteed that the total length of the words won't exceed 105 characters.

The next line contains a single integer n (0 ≤ n ≤ 105) — the number of pairs of words in synonym dictionary. The i-th of the next n lines contains two space-separated non-empty words xi and yi. They mean that word xi can be replaced with word yi (but not vise versa). It is guaranteed that the total length of all pairs of synonyms doesn't exceed 5·105 characters.

All the words at input can only consist of uppercase and lowercase letters of the English alphabet.

Output

Print two integers — the minimum number of letters «R» in an optimal essay and the minimum length of an optimal essay.

输入输出样例

输入样例#1: 
3
AbRb r Zz
4
xR abRb
aA xr
zz Z
xr y
输出样例#1: 
2 6
输入样例#2: 
2
RuruRu fedya
1
ruruRU fedor
输出样例#2: 
1 10




十分气愤!!!
不懂为什么他们机房互模成瘾,实在忍不了。

我太菜了,这么水的题都想不出来...
Noip怕是凉了。
首先我们可以把每个出现的字符串当做一个点,把转化关系当做边。
用一个pair类型存储每个字符串的$r$的个数和长度。
然后贪心地想,我们肯定是要让尽可能多的字符串有尽量少的r和尽量少的长度。
把所有字符串放进队列里bfs,类似spfa,如果能更新的话就再次入队。
最后所有更新完之后的1——n的r的个数和长度一定是最短的。
还要注意字符串会有重复,比较坑。
总之我太菜了。


 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <queue>
#include <map> 
#include <vector>
using namespace std;
#define reg register 
inline char gc() {
    static const int BS = 1 << 22;
    static unsigned char Buf[BS], *st, *ed;
    if (st == ed) ed = Buf + fread(st = Buf, 1, BS, stdin);
    return st == ed ? EOF : *st++;
}
#define gc getchar
inline int read() {
    int res=0;char ch=getchar();bool fu=0;
    while(!isdigit(ch)) {if(ch=='-')fu=1;ch=getchar();}
    while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
    return fu?-res:res;
}
#define ll long long
#define pii pair <ll, ll>
#define mkp make_pair
int n, m;
map <string, int> mp;
int tot;
pii memc[600005];
vector <int> ve[600005];
ll ans1, ans2; 
int cp[600005];

inline void down(string &s)
{
    int len = s.length();
    for (reg int i = 0 ; i < len ; i ++)
        if (s[i] >= 'A' and s[i] <= 'Z') s[i] = s[i] - 'A' + 'a';
}

inline void add(string &s)
{
    int len = s.length();
    down(s);
    ll cnt = 0;
    for (reg int i = 0 ; i < len ; i ++)
        if (s[i] == 'r') cnt++;
    if (mp.find(s) == mp.end()) {
        mp[s] = ++tot;
        memc[tot] = mkp(cnt, len);
    }
}

int main()
{
    n = read();
    for (reg int i = 1 ; i <= n ; i ++)
    {
        string s;
        cin >> s;
        add(s);
        cp[i] = mp[s];
    }
    m = read();
    for (reg int i = 1 ; i <= m ; i ++)
    {
        string s1, s2;
        cin >> s1 >> s2;
        add(s1), add(s2);
        ve[mp[s2]].push_back(mp[s1]);
    }
    queue <int> q;
    for (reg int i = 1 ; i <= tot ; i ++) q.push(i);
    while (!q.empty())
    {
        int x = q.front();q.pop();
        for (reg int i = 0 ; i < ve[x].size() ; i ++)
        {
            int to = ve[x][i];
            if (memc[to] > memc[x]) {
                memc[to] = memc[x];
                q.push(to);
            }
        }
    }
    for (reg int i = 1 ; i <= n ; i ++)
        ans1 += memc[cp[i]].first, ans2 += memc[cp[i]].second;
    printf("%lld %lld\n", ans1, ans2);
    return 0;
}

 



posted @ 2018-09-25 19:28  zZhBr  阅读(258)  评论(0编辑  收藏  举报