• CodeForces 467D(267Div2-D)Fedor and Essay (排序+dfs)


    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

    题意: 给一篇文章的单词,再给m对同义词(单向同义),文章中的单词可以被同义词替换,题目求经过替换后,文章中r字母出现的次数最少是多少次,如果有多个方案,要求长度最短,输出次数和长度

    思路: 把每个单词视为一个点,把所有点都按照r从小到大r相同的sz从小到大的顺序排序,然后每一对同义词就是一条有向边。把单词排序后,遍历单词dfs一遍,对某个单词u,把u的所有后代的r和sz都更新为u的r和sz,最后再更新一遍文章的就ok了。注意sz需要用long long
    #include <bits/stdc++.h>
    #pragma comment(linker, "/STACK:1024000000,1024000000") 
    using namespace std;
    typedef long long ll;
    const int N = 200010;
    
    char s[500010];
    
    struct _node{
        int id;
        int rnum,sz;
        int head;
        friend bool operator < (const _node &a, const  _node &b)
        {
            return a.rnum<b.rnum || (a.rnum==b.rnum && a.sz<b.sz);
        }
    };
    struct _edge{
        int to,next;
    };
    map<string,int> mp;
    int id[N];
    _node mes[N];
    _edge edge[N];
    int ecnt,mescnt;
    int n,m;
    bool vis[N];
    
    int eassyid[N];
    
    void dfs(int u,int r,int s)
    {
        if(vis[u]) return;
        vis[u]=1;
        mes[u].rnum=r;
        mes[u].sz=s;
        for(int e=mes[u].head;e!=-1;e=edge[e].next)
            dfs(id[edge[e].to],r,s);
    }
    
    inline void addedge(int u,int v)
    {
        edge[ecnt].to = v;
        edge[ecnt].next = mes[u].head;
        mes[u].head = ecnt++;
    }
    
    inline void all_lower(int &num,int &sz)
    {
        int i;num=0;
        for(i=0;s[i];i++)
        {
            if(s[i]>='A' && s[i]<='Z')
                s[i]=s[i]-'A'+'a';
            if(s[i]=='r')
                num++;
        }
        sz=i;
    }
    inline int get_id()
    {
        int num,sz;
        all_lower(num,sz);
        string str(s);
        if(mp.find(str)==mp.end())
        {
            mes[mescnt].head=-1;
            mes[mescnt].sz=sz;
            mes[mescnt].rnum=num;
            mes[mescnt].id=mescnt;
            mp[str]=mescnt++;
        }
        return mp[str];
    }
    
    int main()
    {
        #ifdef LOCAL
        freopen("in","r",stdin);
        #endif
        int i;
        ecnt=mescnt=0;
        mp.clear();
        scanf("%d",&m);
        for(i=0;i<m;i++)
        {
            scanf("%s",s);
            eassyid[i]=get_id();
        }
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%s",s);
            int u = get_id();
            scanf("%s",s);
            int v = get_id();
            addedge(v,u);
        }
    //    for(i=0;i<mescnt;i++)
    //        cout<<mes[i].rnum<<' '<<mes[i].sz<<endl;
        sort(mes,mes+mescnt);
        for(i=0;i<mescnt;i++)
            id[mes[i].id]=i;
        memset(vis,0,sizeof(vis));
        for(i=0;i<mescnt;i++)
            if(!vis[i])
                dfs(i,mes[i].rnum,mes[i].sz);
        ll ansr=0,ansz=0;
        for(i=0;i<m;i++)
            ansr+=mes[id[eassyid[i]]].rnum,
            ansz+=mes[id[eassyid[i]]].sz;
        cout<<ansr<<' '<<ansz<<endl;
        return 0;
    }
  • 相关阅读:
    FTP登录 下载上传文件(太过简单暂时未写)
    依据文档批次命名图片
    UDP协议
    tcp协议(三次握手 四次挥手)
    1956年人工智能元年,而今天是我进入人工智能的日子,哈哈哈
    对比文件简易代码
    爬取网站内容,存放到excel中
    Redis-Py 使用
    python list减法
    sort 使用key函数时,赋多个排序参数
  • 原文地址:https://www.cnblogs.com/someblue/p/3989033.html
Copyright © 2020-2023  润新知