一.题目
传送门
翻译:
在你帮助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 long
int 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]