map,vector,queue 图 综合运用

D. Fedor and Essay、、http://codeforces.com/problemset/problem/467/D
 
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Examples
input
Copy
3
AbRb r Zz
4
xR abRb
aA xr
zz Z
xr y
output
Copy
2 6
input
Copy
2
RuruRu fedya
1
ruruRU fedor
output
Copy
1 10
原出处 : https://www.cnblogs.com/xiongtao/p/9916944.html

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#define inf 0x3f3f3f3f
#include<queue>
#include<map>
using namespace std;

typedef long long ll;
const int maxn=1e5+10;

struct node{
    int len;
    int sumr;
}s[2*maxn],p;//s存储编号后,该编号单词可表示最少r数下最短的。 

int tot,n,m,flag[maxn];
map<string, int>mp;
vector<int> v[maxn*2];//存编号后,该编号可以代替的单词编号 

void cl(string& str)//单词处理,将单词编号,并记录其s数组下的值 
{
    int len=str.length();
    int cnt=0;
    for(int i=0;i<len;i++)
    {
        if('A'<=str[i]&&str[i]<='Z')//统一转化成小写字母 
            str[i]=str[i]-'A'+'a';
        if(str[i]=='r')//记录'r'的数量 
            cnt++;
    }
    if(!mp.count(str))//找没出现的单词 使用count,返回的是被查找元素的个数,如果有,返回1;否则,返回0;
    {
        mp[str]=tot;//tot为编号 
        s[tot].len=len;//记录该编号的长度及r数量 
        s[tot++].sumr=cnt;
    }
}

void bfs()//广搜,将每个s代表的单词变成可以表示的最少r数是最短 
{
    queue<int> q;
    for(int i=0;i<tot;i++)
        q.push(i);
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        p=s[t];
        int len=v[t].size();
        for(int i=0;i<len;i++)//和每个可转换单词比较 
        {
            int x=v[t][i];
            if(p.sumr<s[x].sumr)//r数量更少 
            {
                s[x].sumr=p.sumr;
                s[x].len=p.len;
                q.push(x);
            }
            else if(p.sumr==s[x].sumr&&s[x].len>p.len)//r数量相同,长度更短 
            {
                s[x].len=p.len;
                q.push(x);
            }
        }
    }
}

int main()
{
    cin>>n;
    string str1,str2;
    for(int i=0;i<n;i++)
    {
        getchar();
        cin>>str1;
        cl(str1);
        flag[i]=mp[str1];//记录每个单词的编号 
    }
    cin>>m;
    for(int i=0;i<m;i++)
    {
        cin>>str1>>str2;
        cl(str1);
        cl(str2);
        v[mp[str2]].push_back(mp[str1]);//可以取代,用编号表示 
    }
    bfs();//搜索后每个s的单词都是最小 
    ll sum=0,len=0;
    for(int i=0;i<n;i++)//求答案 
    {
        sum+=s[flag[i]].sumr;
        len+=s[flag[i]].len;
    }
    cout<<sum<<" "<<len<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qqshiacm/p/10771853.html