题目链接:

题意:

给定n个单词。

以下有m个替换方式。左边的单词能变成右边的单词。

替换随意次后使得最后字母r个数最少,在r最少的情况下单词总长度最短

输出字母r的个数和单词长度。

思路:

我们觉得一个单词有2个參数。则m个替换规则能够当成m个点的有向图。

则某些单词的替换终点会确定,所以反向建图bfs一下。

为了防止某些点被重复更新,所以把每一个点的权值都放到栈里排个序然后bfs。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<string>
using namespace std; typedef int ll;
const int inf = 1000000;
#define N 300005
int n, m;
void go(string &x){
int len = x.length();
for(int i = 0; i < len; i++)
if('A' <= x[i] && x[i] <= 'Z')
x[i] = x[i]-'A'+'a';
}
string s[N], a[N], b[N];
int S[N], A[N], B[N], LEN[N], NUM[N];
map<string, int> mp;
struct Edge{
int to, nex;
}edge[N*10];
int head[N], edgenum;
void init(){memset(head, -1, sizeof head); edgenum = 0;}
void add(int u, int v){
Edge E = {v, head[u]};
edge[edgenum] = E;
head[u] = edgenum++;
}
struct node{
int x, y, point;
node (int X = 0, int Y = 0, int P = 0):x(X), y(Y), point(P){}
bool operator<(const node&D){
if(D.x!=x)return D.x > x;
return D.y>y;
}
}st[N], dis[N];
int top;
bool cmp(node X, node Y){
if(X.x != Y.x) return X.x < Y.x;
if(X.y != Y.y) return X.y < Y.y;
return X.point < Y.point;
}
int tot;
void BFS(int x){
queue<int>q;
q.push(x);
while(!q.empty()){
int u = q.front(); q.pop();
for(int i = head[u]; ~i; i = edge[i].nex){
int v = edge[i].to;
if(dis[u] < dis[v])
{
dis[v] = dis[u];
q.push(v);
}
}
}
}
void input(){
mp.clear();
init();
top = tot = 0;
for(int i = 1; i <= n; i++)
{
cin>>s[i]; go(s[i]);
if(mp.count(s[i])==0)
{
S[i] = mp[s[i]] = ++tot;
int len = s[i].length(), num = 0;
for(int j = 0; j < len; j++) num += s[i][j]=='r';
st[top++] = node(num, len, tot);
LEN[tot] = len; NUM[tot] = num;
}
else S[i] = mp[s[i]];
}
scanf("%d", &m);
for(int i = 1; i <= m; i++)
{
cin>>a[i]>>b[i]; go(a[i]); go(b[i]);
if(mp.count(a[i])==0)
{
A[i] = mp[a[i]] = ++tot;
int len = a[i].length(), num = 0;
for(int j = 0; j < len; j++) num += a[i][j]=='r';
st[top++] = node(num, len, tot);
LEN[tot] = len; NUM[tot] = num;
}
else A[i] = mp[a[i]];
if(mp.count(b[i])==0)
{
B[i] = mp[b[i]] = ++tot;
int len = b[i].length(), num = 0;
for(int j = 0; j < len; j++) num += b[i][j]=='r';
st[top++] = node(num, len, tot);
LEN[tot] = len; NUM[tot] = num;
}
else B[i] = mp[b[i]];
add(B[i], A[i]);
}
}
int main(){
while(~scanf("%d", &n)){
input();
for(int i = 1; i <= tot; i++)dis[i] = node(NUM[i], LEN[i],0);
sort(st, st+top, cmp);
for(int i = 0; i < top; i++)
BFS(st[i].point);
long long ans1 = 0, ans2 = 0;
for(int i = 1; i <= n; i++)
ans1 += dis[S[i]].x, ans2 += dis[S[i]].y; printf("%I64d %I64d\n", ans1, ans2);
}
return 0;
}

Codeforces 467D Fedor and Essay bfs的更多相关文章

  1. CodeForces 467D(267Div2-D)Fedor and Essay (排序+dfs)

    D. Fedor and Essay time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. Codeforces Round #267 (Div. 2) D. Fedor and Essay tarjan缩点

    D. Fedor and Essay time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. CF467D Fedor and Essay 建图DFS

      Codeforces Round #267 (Div. 2) CF#267D D - Fedor and Essay D. Fedor and Essay time limit per test ...

  4. Codeforces 467D

    题目链接 D. Fedor and Essay time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  5. 【Codeforces 467D】Fedor and Essay

    Codeforces 467 D 题意:给\(m​\)个单词,以及\(n​\)个置换关系,问将\(m​\)个单词替换多次后其中所含的最少的\(R​\)的数量以及满足这个数量的最短总长度 思路:首先将置 ...

  6. Codeforces Round #267 Div.2 D Fedor and Essay -- 强连通 DFS

    题意:给一篇文章,再给一些单词替换关系a b,表示单词a可被b替换,可多次替换,问最后把这篇文章替换后(或不替换)能达到的最小的'r'的个数是多少,如果'r'的个数相等,那么尽量是文章最短. 解法:易 ...

  7. [CF467D] Fedor and Essay

    After you had helped Fedor to find friends in the «Call of Soldiers 3» game, he stopped studying com ...

  8. Codeforces gym 100685 F. Flood bfs

    F. FloodTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/F Desc ...

  9. CodeForces 540C Ice Cave (BFS)

    http://codeforces.com/problemset/problem/540/C       Ice Cave Time Limit:2000MS     Memory Limit:262 ...

随机推荐

  1. VIM使用技巧2

    假如有以下程序片段: var foo = 1 var bar = 'a' var foobar = foo + bar 如果我们想在每行行尾加上分号, (1)使用$移动光标到行尾, (2)执行a;&l ...

  2. [SaltStack] Crontab部署

    salt.states.cron 接着早上安静的时间, 在这里梳理下crontab相关的东东, 主要是crontab的统一管理维护, 包括新增, 修改, 下线等等. 下面就详细看下crontab的sl ...

  3. git使用代理clone加速

    不设置代理10kb/s不到....,设置后,500kb/s左右跑- 开shadowsocks,代理127.0.0.1:1080 编写一个脚本 /YOUR PATH/gitproxy.sh #!/bin ...

  4. 只用一次循环开销 将类似 1 A 、1 B 的数据返回成为 1 A,B 的拼接形式

    /// <summary> ///将类似 1 A .1 B 的数据返回成为 1 A,B 的拼接形式 /// </summary> /// <param name=&quo ...

  5. Block为什么使用Copy?

    block:本质就是一个object-c对象block:存储位置,可能分为3个地方:代码去,堆区.栈区(ARC情况下会自动拷贝到堆区,因此ARC下只能有两个地方:代码去.堆区)代码区:不访问栈区的变量 ...

  6. codevs_1043 方格取数(棋盘DP)

    1043 方格取数 2000年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description ...

  7. Java线程池ThreadPoolExecutor类源码分析

    前面我们在java线程池ThreadPoolExecutor类使用详解中对ThreadPoolExector线程池类的使用进行了详细阐述,这篇文章我们对其具体的源码进行一下分析和总结: 首先我们看下T ...

  8. Java基础教程---JDK的安装和环境变量的配置

    一.Java的安装和环境变量配置 1.Java的安装: 第一步,从Oracle官网下载安装包,当然也可以从其他安全可靠的地方下载(PS:根据不同电脑系统下载相应的安装包,注意电脑的位数.如x64,x3 ...

  9. BZOJ 4011 HNOI2015 落忆枫音

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=4011 题目很长,写得也很有诗意与浪漫色彩,让我们不禁感叹出题人是一个多么英俊潇洒的人. 所 ...

  10. vs2013 x64 编译汇编代码

    x64不再支持__asm, 只能单独放在一个.asm中. xxx.asm--------属性 应用    会出现 自定义生成工具.  下面黑体是我们修改的内容.