D. Fedor and Essay
题意:一篇文章由m个单词组成,你需要重写这篇文章。有n组同义词(x,y),x能用y代替,反过来不行。重写文章使得文章中含有最少的'r',且总字符数尽量少。
思路:先把所有大写字母转换成小写,然后用map把每个不同的单词转化成一个整型,建图,再用tarjan强连通缩点(因为可能有环)。。然后在缩点后的新图中dfs求解(DAG上的问题)。这是我写的第一道强连通缩点,调了好久。。。
#include <iostream>
#include <stdio.h>
#include <string>
#include <map>
#include <vector>
#include <stack>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN=100010;
int m,n;
struct Node{
int r;
int len;
bool operator<(const Node nd)const{
if(r==nd.r)return len<nd.len;
return r<nd.r;
}
}node[MAXN*2];
string words[MAXN];
vector<int> oriG[MAXN*2];
vector<int> G[MAXN*2];
int cnt;
map<string,int> mp;
int hash_str(string& str){
if(!mp.count(str)){
int len=str.length();
int r=0;
for(int i=0;i<len;i++){
if(str[i]=='r')r++;
}
node[cnt].len=len;
node[cnt].r=r;
mp[str]=cnt++;
return cnt-1;
}
return mp[str];
}
int dfn[MAXN*2];
int low[MAXN*2];
bool instack[MAXN*2];
stack<int> sta;
int belong[MAXN*2];
int dfs_clock;
void tarjan(int u){
dfn[u]=low[u]=++dfs_clock;
sta.push(u);
instack[u]=1;
int sz=oriG[u].size();
for(int i=0;i<sz;i++){
int v=oriG[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(instack[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
while(1){
int t=sta.top(); sta.pop(); instack[t]=0;
belong[t]=u;
if(t==u)break;
if(node[t]<node[u])node[u]=node[t];
}
}
}
bool vis[MAXN*2];
void dfs(int u){
vis[u]=1;
int sz=G[u].size();
for(int i=0;i<sz;i++){
int v=G[u][i];
if(!vis[v])dfs(v);
if(node[v]<node[u])node[u]=node[v];
}
}
void init(){
dfs_clock=0;
cnt=0;
}
int main(){
init();
cin>>m;
for(int i=0;i<m;i++){
cin>>words[i];
transform(words[i].begin(),words[i].end(),words[i].begin(), ::tolower);
}
cin>>n;
string x,y;
for(int i=0;i<n;i++){
cin>>x>>y;
transform(x.begin(),x.end(),x.begin(), ::tolower);
transform(y.begin(),y.end(),y.begin(), ::tolower);
int u=hash_str(x);
int v=hash_str(y);
oriG[u].push_back(v);
}
for(int i=0;i<cnt;i++){
if(!dfn[i])tarjan(i);
}
for(int i=0;i<cnt;i++){
int sz=oriG[i].size();
for(int j=0;j<sz;j++){
int v=oriG[i][j];
if(belong[i]==belong[v])continue;
G[belong[i]].push_back(belong[v]);
}
}
for(int i=0;i<cnt;i++){
int u=belong[i];
if(!vis[u]){
dfs(u);
}
}
long long ansr=0;
long long anslen=0;
for(int i=0;i<m;i++){
if(mp.count(words[i])){
int t=belong[mp[words[i]]];
ansr+=node[t].r;
anslen+=node[t].len;
}else{
int len=words[i].length();
anslen+=len;
for(int j=0;j<len;j++){
if(words[i][j]=='r')ansr++;
}
}
}
cout<<ansr<<" "<<anslen<<endl;
return 0;
}