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;
}

 

posted on 2018-01-18 21:23  2855669158  阅读(89)  评论(0编辑  收藏  举报

导航