• Codeforces467 Fedor and Essay


    题意:输入m个字符串,以及n种关系,这n种关系的两个字符串可以由前面替换为后面,要让原文的r个数最少且最短

    题解:这n对关系可以发现是一个有向图,每一个图一个点权(t的个数,长度),直接暴力对原文每一个字符串进行搜索会超时,所以可以在图上搜索,把每一个点更新为最小,要反向更新,所以这里是建反向边

    #include <bits/stdc++.h>
    #define maxn 101000
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    pii vec[maxn];
    ll cnt = 0, ans1, ans2, m, n, c[maxn], t1, t2, dir[maxn];
    vector<int>G[maxn];
    map<string ,int>mp;
    string s, s1, s2;
    ll in[maxn];
    ll add(string &s){
        ll t = 0;
        for(ll i=0;i<s.length();i++){
            if(s[i]<='Z'&&s[i]>='A')
                s[i] = s[i]-'A'+'a';
            if(s[i] == 'r') t++;
        }
        if(!mp.count(s)){
            mp[s] = cnt;
            vec[cnt] = make_pair(t, s.length());
            cnt++;
        }
        return mp[s];
    }
    void bfs(){
        queue<ll >q;
        for(ll i=0;i<cnt;i++) q.push(i);
        while(!q.empty()){
            ll idx = q.front();
            pii u = vec[idx];
            q.pop();
            for(ll i=0;i<G[idx].size();i++){
                ll v = G[idx][i];
                if(vec[v] > u){
                    vec[v] = u;
                    q.push(v);
                }
            }
        }
    }
    int main(){
        cin>>m;
        for(ll i=0;i<m;i++) cin>>s, c[i] = add(s);
        cin>>n;
        for(ll i=0;i<n;i++){
            cin>>s1>>s2;
            ll a = add(s1);
            ll b = add(s2);
            G[b].push_back(a);
        }
        bfs();
        for(ll i=0;i<m;i++){
            ans1 += vec[c[i]].first;
            ans2 += vec[c[i]].second;
        }
        cout<<ans1<<" "<<ans2<<endl;
        return 0;
    }
  • 相关阅读:
    PHP发送邮件(php100视频后笔记)
    简单页面访问统计
    怎样制作RSS源
    r给自己网站/博客制作安卓应用程序
    反射简单概念
    笔记本
    使用IHttpModule实现简单的页面重映射Url
    工厂方法模式与抽象工厂模式的区别
    安装TFS2010实际体验
    限定登录失败次数,超过指定次数就限制登录一段时间
  • 原文地址:https://www.cnblogs.com/Noevon/p/8313105.html
Copyright © 2020-2023  润新知