zoukankan      html  css  js  c++  java
  • Codeforces 467D

    题目链接

    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 nlines 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
    
    
      1 /*************************************************************************
      2     > File Name: D.cpp
      3     > Author: Stomach_ache
      4     > Mail: sudaweitong@gmail.com
      5     > Created Time: 2014年09月19日 星期五 14时41分44秒
      6     > Propose: 
      7  ************************************************************************/
      8 #include <map>
      9 #include <cmath>
     10 #include <string>
     11 #include <cstdio>
     12 #include <vector>
     13 #include <fstream>
     14 #include <cstring>
     15 #include <iostream>
     16 #include <algorithm>
     17 using namespace std;
     18 /*Let's fight!!!*/
     19 
     20 const int MAX_N = 100050;
     21 const int INF = 0x3f3f3f3f;
     22 typedef pair<int, int> pii;
     23 typedef long long LL;
     24 
     25 int V; // 顶点数
     26 vector<int> G[MAX_N], rG[MAX_N], vs;
     27 bool used[MAX_N];
     28 int cmp[MAX_N];
     29 //题目变量
     30 map<string, int> HASH;
     31 int n, m, ID[MAX_N], X[MAX_N], Y[MAX_N];
     32 pii s[MAX_N], ss[MAX_N], dp[MAX_N];
     33 
     34 void add_edge(int from, int to) {
     35     G[from].push_back(to);
     36     rG[to].push_back(from);
     37 }
     38 
     39 void dfs(int v) {
     40     used[v] = true;
     41     for (int i = 0; i < G[v].size(); i++) {
     42           if (!used[G[v][i]]) dfs(G[v][i]);
     43     }
     44     vs.push_back(v);
     45 }
     46 
     47 void rdfs(int v, int k) {
     48     used[v] = true;
     49     cmp[v] = k;
     50     ss[k] = min(ss[k], s[v]);
     51     for (int i = 0; i < rG[v].size(); i++) {
     52         if (!used[rG[v][i]]) rdfs(rG[v][i], k);
     53     }
     54 }
     55 
     56 int scc() {
     57     memset(used, false, sizeof(used));
     58     vs.clear();
     59     for (int v = 1; v <= V; v++) {
     60           if (!used[v]) dfs(v);
     61     }
     62     memset(used, false, sizeof(used));
     63     int k = 0;
     64     for (int i = vs.size() - 1; i >= 0; i--) {
     65           if (!used[vs[i]]) {
     66             ss[++k] = pii(INF, INF);
     67             rdfs(vs[i], k);
     68         }
     69     }
     70     return k;
     71 }
     72 
     73 
     74 int get(string &str) {
     75     for (int i = 0;  i < str.size(); i++) {
     76         str[i] = tolower(str[i]);
     77     }
     78     if (HASH.find(str) == HASH.end()) {
     79         HASH[str] = ++V;
     80         s[V].second= str.size();
     81         for (int j = 0; j < s[V].second; j++) if (str[j] == 'r') s[V].first++;
     82         return V;
     83     } else {
     84         return HASH[str];
     85     }
     86 }
     87 
     88 void rebuild() {
     89     for (int i = 1; i <= V; i++) G[i].clear();
     90     for (int i = 1; i <= m; i++) if (cmp[X[i]] != cmp[Y[i]]) 
     91         add_edge(cmp[X[i]], cmp[Y[i]]);
     92 }
     93 
     94 pii DFS(int u) {
     95     if (used[u]) return dp[u];
     96     used[u] = true;
     97     dp[u] = ss[u];
     98     for (int i = 0; i < G[u].size(); i++) {
     99         dp[u] = min(dp[u], DFS(G[u][i]));
    100     }
    101     return dp[u];
    102 }
    103 
    104 int main(void) {
    105     ios::sync_with_stdio(false);
    106     cin >> n;
    107     for (int i = 1; i <= n; i++) {
    108         string str;
    109         cin >> str;
    110         int id = get(str);
    111         ID[i] = id;
    112     }
    113 
    114     cin >> m;
    115     for (int i = 1; i <= m; i++) {
    116         string x, y;
    117         cin >> x >> y;
    118         int u = get(x), v = get(y);
    119         add_edge(u, v);
    120         X[i] = u, Y[i] = v;
    121     }
    122 
    123     int k = scc();
    124     rebuild();
    125 
    126     memset(used, false, sizeof(used));
    127     LL resr = 0, resl = 0;
    128     for (int i = 1; i <= n; i++) {
    129         int pos = cmp[ID[i]];
    130         DFS(pos);
    131         resr += dp[pos].first;
    132         resl += dp[pos].second;
    133     }
    134 
    135     cout << resr << ' ' << resl << endl;
    136     return 0;
    137 }
    
    
    
    
    
    
    
  • 相关阅读:
    bzoj 1761: [Baltic2009]beetle 区间dp
    NOI冲刺计划
    bzoj 2107: Spoj2832 Find The Determinant III 辗转相除法
    bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树
    bzoj 1209: [HNOI2004]最佳包裹 三维凸包
    SCOI2015题解 && 考试小结
    bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
    考场上应该想到。。。。
    spoj LCS 后缀自动机
    BZOJ 1639: [Usaco2007 Mar]Monthly Expense 月度开支
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3982585.html
Copyright © 2011-2022 走看看