• Codeforces Round #267 (Div. 2) D. Fedor and Essay


    D. Fedor and Essay
    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.

    Sample test(s)
    input
    3
    AbRb r Zz
    4
    xR abRb
    aA xr
    zz Z
    xr y
    output
    2 6
    input
    2
    RuruRu fedya
    1
    ruruRU fedor
    output
    1 10

     思路:缩点+dp

    没算到会用long long ==,好像最近经常会被long long 卡================

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<set>
    #include<stack>
    #include<map>
    #include<ctime>
    #include<bitset>
    #define LL unsigned long long
    #define mod 20140518
    #define maxn 300010
    #define INF 0x3f3f3f
    using namespace std;
    
    vector<int>qe[maxn] ;
    int pre[maxn],low[maxn] ,dfs_time;
    int val[maxn],e[maxn] ;
    int cnt,scc[maxn];
    LL dp[maxn][2];
    map<string,int>mm;
    bool vi[maxn] ;
    stack<int>s;
    void dfs( int u )
    {
        pre[u] = low[u] = ++dfs_time ;
        int i , v ;
        s.push(u) ;
        vi[u] = 1 ;
        for( i = 0 ; i < qe[u].size() ; i++ )
        {
            v = qe[u][i] ;
            if(!pre[v]){
                dfs(v) ;
                 low[u] = min(low[u],low[v]) ;
            }
            if( vi[v] && pre[v] < low[u])
                low[u] = pre[v] ;
        }
        if(pre[u] == low[u])
        {
            cnt++ ;
            while(1)
            {
                v = s.top() ; s.pop() ;
                scc[v] = cnt ;
                vi[v] = 0;
                if(v==u) break ;
            }
        }
        return ;
    }
    char a[500010] ,b[500010];
    int id[maxn] ;
    char map1[200] ;
    void dfs(int u,int sz)
    {
        vi[u] = true;
        if(dp[scc[u]][0] > val[u])
        {
            dp[scc[u]][0] = val[u] ;
            dp[scc[u]][1] = e[u] ;
        }
        else if(dp[scc[u]][0] == val[u] && dp[scc[u]][1] > e[u])
            dp[scc[u]][1] = e[u] ;
        int v,id;
        for( int i = 0 ; i < qe[u].size();i++)
        {
            v = qe[u][i] ;
            if(vi[v]){
                        if(dp[scc[v]][0] < dp[scc[u]][0])
                        {
                            dp[scc[u]][0] = dp[scc[v]][0];
                            dp[scc[u]][1] = dp[scc[v]][1];
                        }
                        else  if(dp[scc[v]][0] == dp[scc[u]][0] &&dp[scc[v]][1] < dp[scc[u]][1] )
                        {
                            dp[scc[u]][1] = dp[scc[v]][1];
                        }
                        continue ;
            }
            dfs(v,sz) ;
            if(scc[v]==scc[u]) continue ;
            if(dp[scc[v]][0] < dp[scc[u]][0])
            {
                dp[scc[u]][0] = dp[scc[v]][0];
                dp[scc[u]][1] = dp[scc[v]][1];
            }
            else  if(dp[scc[v]][0] == dp[scc[u]][0] &&dp[scc[v]][1] < dp[scc[u]][1] )
            {
                dp[scc[u]][1] = dp[scc[v]][1];
            }
        }
    }
    int main()
    {
        int i,j,k,m ,cnt1;
        int n,T ,u,v,c ;
        c = 'a' ;
        for( i = 'A' ; i <= 'Z' ;i++){
            map1[i] = (char)c ;
            map1[c] = (char)c;
            c++;
        }
        scanf("%d",&n);
             cnt1=0;
             int num ;
             for( i = 1 ; i <= n ;i++)
             {
                 scanf("%s",a) ;
                 m = strlen(a) ;
                 num=0;
                 for( j = 0 ; j < m ;j++)
                 {
                    a[j] = map1[a[j]];
                    if(a[j]=='r')num++;
                 }
                 if(!mm[a])
                 {
                     mm[a] = ++cnt1;
                     val[cnt1] = num ;
                     e[cnt1] = m ;
                     id[i]=cnt1 ;
                 }
                 else id[i] = mm[a] ;
             }
             scanf("%d",&k) ;
             while(k--)
             {
                 scanf("%s%s",a,b) ;
                 m = strlen(a) ;
                 num=0;
                 for( j = 0 ; j < m ;j++)
                 {
                     a[j] = map1[a[j]];
                    if(a[j]=='r')num++;
                 }
                 if(!mm[a])
                 {
                     mm[a]=++cnt1;
                     val[cnt1] = num ;
                     e[cnt1] = m ;
                     u = cnt1 ;
                 }
                 else u = mm[a] ;
                 m = strlen(b) ;
                 num=0;
                 for( j = 0 ; j < m ;j++)
                 {
                    b[j] = map1[b[j]];
                    if(b[j]=='r')num++;
                 }
                 b[m]='';
                 if(!mm[b])
                 {
                     mm[b]=++cnt1;
                     val[cnt1] = num ;
                     e[cnt1] = m ;
                     v = cnt1 ;
                 }
                 else v = mm[b] ;
                 qe[u].push_back(v);
             }
             for( i =1 ; i <= cnt1 ;i++)if(!pre[i])
                dfs(i) ;
             LL ans1=0,ans2=0;
             u = 1;
             memset(vi,0,sizeof(vi)) ;
             memset(dp,0x3f3f3f,sizeof(dp)) ;
             for( i = 1 ; i <= n ;i++)
             {
                 v = id[i] ;
                 if(!vi[v])
                 dfs(v,u) ;
                 ans1 += dp[scc[v]][0] ;
                 ans2 += dp[scc[v]][1] ;
             }
             printf("%I64d %I64d
    ",ans1,ans2) ;
        return 0 ;
    }
    

      

  • 相关阅读:
    页面滚屏截图工具推荐
    java总结第二次(剩余内容)//类和对象1
    happy birthday to tbdd tomorrow
    数组增删改查及冒泡
    三个循环方面程序
    三个入门小程序
    java总结第二次//数组及面向对象
    Java总结第一次//有些图片未显示,文章包含基础java语言及各种语句
    后台验证url是不是有效的链接
    img 鼠标滑上后图片放大,滑下后图片复原
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/3980802.html
Copyright © 2020-2023  润新知