文章目录

  • 一.题目
  • 二.题解
  • 三.Code
  • Thanks!

一.题目

传送门
翻译:
在你帮助Fedor在«Call of Soldiers 3»这款游戏中找到朋友之后,他完全停止了学习。今天,英语老师让他准备一篇文章。 Fedor并不想准备这篇文章,所以他向Alex寻求帮助。Alex来帮忙并为Fedor写了一篇文章。但Fedor根本不喜欢这篇文章。现在Fedor将使用英语同义词词典来重写文章。

Fedor不想改变文章的含义。因此,他将做的唯一改变是:根据字典中的替换规则,将一个论文中的单词改为它的一个同义词。 Fedor可以多次执行此操作。

因此,Fedor希望得到一篇文章,其中包含尽可能少的字母“R”(样例无关)。如果有多篇论文都有最小数量的“R”,那么他希望得到一个最小长度的论文(论文的长度是其中所有单词长度的总和)。帮助Fedor获得所需的论文。

请注意,在这个问题中,字母的大小写情况无关紧要。例如,如果同义词词典说单词cat可以用单词DOG替换,则允许用单词doG替换单词Cat。

二.题解

乍一看一个字符串的题跟强连通分量有什么关系?QWQ
其实关系大。对于每一个单词向可以替换它的单词连一条有向边,每个单词内r的数量即点权,然后我们用 m i n n 1 [ i ] minn1[i] minn1[i]存每个连通块内的单词中字母r的最少个数,用 m i n n 2 [ i ] minn2[i] minn2[i]存每个连通块内的单词的最短长度。
先做一遍Tarjan求有向图强连通分量,然后再缩点做一个树形DP,用来更新 m i n n 1 [ i ] , m i n n 2 [ i ] minn1[i],minn2[i] minn1[i],minn2[i]。这道题就愉快地解决了。
至于存单词,用map就行了。

三.Code

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <map>
using namespace std;#define M 500005
#define LL long longint n, m, dfn[M], low[M], cnt, num, val[M], len[M], sz, minn1[M], minn2[M], belong[M], id[M];
bool vis[M], instack[M];
LL ans1, ans2;
vector <int> G[M];
vector <int> G1[M];
stack <int> s;
map <string, int> mp;void Tarjan (int x){dfn[x] = low[x] = ++ cnt;s.push(x);instack[x] = 1;for (int i = 0; i < G[x].size(); i ++){int tmp = G[x][i];if (! dfn[tmp]){Tarjan (tmp);low[x] = min (low[x], low[tmp]);}else if (instack[tmp]){low[x] = min (low[x], dfn[tmp]);}}if (low[x] == dfn[x]){num ++;int v;do{v = s.top();s.pop();instack[v] = 0;belong[v] = num;if (val[v] < minn1[num] || (val[v] == minn1[num] && len[v] < minn2[num]))minn1[num] = val[v], minn2[num] = len[v];}while (v != x);}
}
void dp (int x){if (vis[x])return ;vis[x] = 1;for (int i = 0; i < G1[x].size(); i ++){int tmp = G1[x][i];dp (tmp);if (minn1[tmp] < minn1[x])minn1[x] = minn1[tmp], minn2[x] = minn2[tmp];else if (minn1[tmp] == minn1[x])minn2[x] = min (minn2[x], minn2[tmp]);}
}
int main (){memset (minn1, 0x3f, sizeof minn1);memset (minn2, 0x3f, sizeof minn2);scanf ("%d", &m);for (int i = 1; i <= m; i ++){char ch[M];scanf ("%s", ch);int l = strlen (ch), ns = 0;for (int j = 0; j < l; j ++){if (ch[j] >= 'A' && ch[j] <= 'Z')   ch[j] = ch[j] - 'A' + 'a';if (ch[j] == 'r')   ns ++;}int t = mp[ch];if (! t)mp[ch] = t = ++ sz;val[t] = ns, len[t] = l;id[i] = t;}scanf ("%d", &n);for (int i = 1; i <= n; i ++){char ch[M];scanf ("%s", ch);int x = strlen (ch), s = 0;for (int j = 0; j < x; j ++){if (ch[j] >= 'A' && ch[j] <= 'Z') ch[j] = ch[j] - 'A' + 'a';if (ch[j] == 'r')  s ++;}int t1 = mp[ch];if (! t1)mp[ch] = t1 = ++ sz;val[t1] = s, len[t1] = x;scanf ("%s", ch);x = strlen (ch), s = 0;for (int j = 0; j < x; j ++){if (ch[j] >= 'A' && ch[j] <= 'Z') ch[j] = ch[j] - 'A' + 'a';if (ch[j] == 'r')  s ++;}int t2 = mp[ch];if (! t2)mp[ch] = t2 = ++ sz;val[t2] = s, len[t2] = x;G[t1].push_back (t2);}for (int i = 1; i <= sz; i ++)if (! dfn[i])Tarjan (i);for (int i = 1; i <= sz; i ++){for (int j = 0; j < G[i].size (); j ++){int tmp = G[i][j];if (belong[i] != belong[tmp])G1[belong[i]].push_back (belong[tmp]);}}for (int i = 1; i <= num; i ++)dp (i);for (int i = 1; i <= m; i ++)ans1 = ans1 + 1ll * minn1[belong[id[i]]], ans2 = ans2 + 1ll * minn2[belong[id[i]]];printf ("%lld %lld\n", ans1, ans2);return 0;
}

Thanks!

CF467D Fedor and Essay 有向图强连通分量+缩点相关推荐

  1. POJ-1236(有向图强连通分量 + 缩点 + 加边使得整个图强连通)

    题目:http://poj.org/problem?id=1236 感觉是强连通问题的一道典型题目,还是有很多地方没有注意到,看了discuss才发现: (1)当整个图已经是一个SCC时 (2)对于S ...

  2. Tarjan有向图强连通分量

    Tarjan有向图强连通分量 本文仅供娱乐,不喜勿喷 一.强连通分量 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi ...

  3. The King’s Problem(tarjan求强连通分量缩点+匈牙利求有向无环图的最小路径覆盖)

    Link:http://acm.hdu.edu.cn/showproblem.php?pid=3861 The King's Problem Time Limit: 2000/1000 MS (Jav ...

  4. 图论学习-有向图强连通分量

    文章目录 有向图强连通分量 1.定义: 2.基本术语与概念 2.1 边的概念 2.2 缩点 2.3 时间戳 3. tarjan求强连通分量(SCC) 3.1 原理 3.2 步骤 3.3 模板 3.3. ...

  5. 有向图强连通分量之Tarjan算法

    出处https://www.byvoid.com/zhs/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...

  6. tarjan算法总结 (强连通分量+缩点+割点),看这一篇就够了~

    文章目录 一.tarjan求强连通分量 1:算法流程 2:模板 二.tarjan缩点 1:相关定义 2:算法流程 三.tarjan求割点.桥 1.什么是割点 2.割点怎么求? 3.割点tarjan模板 ...

  7. POJ 2186 Popular Cows(强连通分量缩点,Tarjan算法)

    [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16578 [解题报告] 给你一个有向图,问你有多少个点可以被其它 ...

  8. Targan 算法[有向图强连通分量]

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(stronglyconnected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大 ...

  9. POJ1236Network of Schools——强连通分量缩点建图

    [题目描述] A number of schools are connected to a computer network. Agreements have been developed among ...

最新文章

  1. 追加10亿!腾讯宣布设立15亿元“战疫基金”
  2. 利用tab_control控件在对话框中加入属性页的方法详细介绍
  3. [Nowcoder] 寻找子串
  4. UA MATH563 概率论的数学基础2 随机变量1 随机变量与分布函数
  5. 机器学习基础-岭回归-06
  6. 谷歌云计算机,google云计算的三大核心技术
  7. 博客已从百度空间搬家到此
  8. 前端用sql 还是mysql_前端小白安装MySQL的踩坑路
  9. 工作之后如何高效的学习?
  10. javascript小技巧:同步服务器时间、同步倒计时
  11. MFS 高可用存储分布式文件系统
  12. r语言html函数,【R语言】《R语言初学者指南》:函数、自定义函数、循环
  13. Python实战RBF神经网络
  14. 日本java图书馆_菜鸡的Java笔记 图书馆
  15. Android10 系统接口 设置屏幕亮度
  16. ros系列—解决文件改名导致节点无法启动问题及ros::NodeHandle nh与nh(“~“)的理解
  17. 哔哩哔哩自动播放视频
  18. 游戏设计的艺术和技术
  19. 【DL】第 6 章:文本生成转换器
  20. ISCSLP 2022 | AccentSpeech—从众包数据中学习口音来构建目标说话人的口音语音合成系统

热门文章

  1. Linux下使用ClamAV病毒查杀
  2. 论文怎么添加引用参考文献(附word添加引用标注教程)
  3. 钢之炼金术师之扉の向こうへ铃声 钢之炼金术师之扉の向こうへ...
  4. 从百亿到万亿:如何打造一支承担企业战略使命的研发团队
  5. 摩托罗拉edge系列双新机发布,打造亿级像素轻薄新旗舰
  6. 使用Rails和Dragonfly上传文件
  7. CSS 块级元素和行内元素
  8. 阿里大数据比赛排名获取2
  9. IT人才才懂的段子,网友们一脸懵|程序猿:哈哈哈哈
  10. 另一种 Vue 中 keep-alive 控制方法