zoukankan      html  css  js  c++  java
  • Codeforces Round #267 (Div. 2) D. Fedor and Essay tarjan缩点

    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.

    Examples
    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

    题意:给你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
    ",ans,out);
        return 0;
    }
  • 相关阅读:
    管理页面的类 PageHelper
    接下来打算写一下visual stuido 2013使用git进行远端管理。
    转一下网上找来的tortoise git不用每次都输入邮箱和密码的方法。备查看
    tortoise git使用 git版本库的rsa key来进行ssh连接
    2015年4月1日 14:36:56 EF 主从表更新
    Oop分析方法
    Knative 实战:基于 Knative Serverless 技术实现天气服务-下篇
    超大规模商用 K8s 场景下,阿里巴巴如何动态解决容器资源的按需分配问题?
    从零开始入门 K8s | 可观测性:你的应用健康吗?
    Knative 暂时不会捐给任何基金会 | 云原生生态周报 Vol. 22
  • 原文地址:https://www.cnblogs.com/jhz033/p/7287199.html
Copyright © 2011-2022 走看看