CF467D Fedor and Essay 有向图强连通分量+缩点
文章目录
- 一.题目
- 二.题解
- 三.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 有向图强连通分量+缩点相关推荐
- POJ-1236(有向图强连通分量 + 缩点 + 加边使得整个图强连通)
题目:http://poj.org/problem?id=1236 感觉是强连通问题的一道典型题目,还是有很多地方没有注意到,看了discuss才发现: (1)当整个图已经是一个SCC时 (2)对于S ...
- Tarjan有向图强连通分量
Tarjan有向图强连通分量 本文仅供娱乐,不喜勿喷 一.强连通分量 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi ...
- 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 ...
- 图论学习-有向图强连通分量
文章目录 有向图强连通分量 1.定义: 2.基本术语与概念 2.1 边的概念 2.2 缩点 2.3 时间戳 3. tarjan求强连通分量(SCC) 3.1 原理 3.2 步骤 3.3 模板 3.3. ...
- 有向图强连通分量之Tarjan算法
出处https://www.byvoid.com/zhs/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...
- tarjan算法总结 (强连通分量+缩点+割点),看这一篇就够了~
文章目录 一.tarjan求强连通分量 1:算法流程 2:模板 二.tarjan缩点 1:相关定义 2:算法流程 三.tarjan求割点.桥 1.什么是割点 2.割点怎么求? 3.割点tarjan模板 ...
- POJ 2186 Popular Cows(强连通分量缩点,Tarjan算法)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16578 [解题报告] 给你一个有向图,问你有多少个点可以被其它 ...
- Targan 算法[有向图强连通分量]
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(stronglyconnected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大 ...
- POJ1236Network of Schools——强连通分量缩点建图
[题目描述] A number of schools are connected to a computer network. Agreements have been developed among ...
最新文章
- 追加10亿!腾讯宣布设立15亿元“战疫基金”
- 利用tab_control控件在对话框中加入属性页的方法详细介绍
- [Nowcoder] 寻找子串
- UA MATH563 概率论的数学基础2 随机变量1 随机变量与分布函数
- 机器学习基础-岭回归-06
- 谷歌云计算机,google云计算的三大核心技术
- 博客已从百度空间搬家到此
- 前端用sql 还是mysql_前端小白安装MySQL的踩坑路
- 工作之后如何高效的学习?
- javascript小技巧:同步服务器时间、同步倒计时
- MFS 高可用存储分布式文件系统
- r语言html函数,【R语言】《R语言初学者指南》:函数、自定义函数、循环
- Python实战RBF神经网络
- 日本java图书馆_菜鸡的Java笔记 图书馆
- Android10 系统接口 设置屏幕亮度
- ros系列—解决文件改名导致节点无法启动问题及ros::NodeHandle nh与nh(“~“)的理解
- 哔哩哔哩自动播放视频
- 游戏设计的艺术和技术
- 【DL】第 6 章:文本生成转换器
- ISCSLP 2022 | AccentSpeech—从众包数据中学习口音来构建目标说话人的口音语音合成系统