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

解法:易知单词间有二元关系,我们将每个二元关系建有向边,然后得出一张图,图中可能有强连通分量(环等),所以找出所有的强连通分量缩点,那个点的minR,Len赋为强连通分量中最小的minR,Len,然后重新建图,跑一个dfs即可得出每个强连通分量的minR,Len,最后O(n)扫一遍替换单词,统计即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <map>
#define INF 0x3f3f3f3f
#define lll __int64
using namespace std;
#define N 100007 struct Edge
{
int v,next;
}G[*N],G2[*N];
string ss[N];
map<string,int> mp;
int minR[*N],Len[*N];
int nR[*N],nLen[*N];
int head[*N],tot,cnt,vis[*N];
int last[*N],tot2;
stack<int> stk;
int instk[*N],now,Time;
int low[*N],dfn[*N],bel[*N];
lll sumR,sumLen; void addedge(int u,int v)
{
G[tot].v = v;
G[tot].next = head[u];
head[u] = tot++;
} void addedge2(int u,int v) //建新图
{
G2[tot2].v = v;
G2[tot2].next = last[u];
last[u] = tot2++;
} void tarjan(int u)
{
low[u] = dfn[u] = ++Time;
stk.push(u);
instk[u] = ;
for(int i=head[u];i!=-;i=G[i].next)
{
int v = G[i].v;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(instk[v])
low[u] = min(low[u],dfn[v]);
}
if(low[u] == dfn[u])
{
cnt++;
int v;
do{
v = stk.top();
stk.pop();
instk[v] = ;
bel[v] = cnt;
if(minR[v] < nR[cnt] || (minR[v] == nR[cnt] && Len[v] < nLen[cnt]))
nR[cnt] = minR[v],nLen[cnt] = Len[v];
}while(u != v);
}
} void Tarjan()
{
memset(bel,,sizeof(bel));
memset(instk,,sizeof(instk));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
Time = ,cnt = ;
while(!stk.empty()) stk.pop();
int i;
for(i=;i<=now;i++)
if(!dfn[i])
tarjan(i);
} void Build()
{
int i,j;
memset(last,-,sizeof(last));
tot2 = ;
for(i=;i<=now;i++)
{
for(j=head[i];j!=-;j=G[j].next)
{
int v = G[j].v;
if(bel[i] != bel[v])
addedge2(bel[i],bel[v]);
}
}
} void dfs(int u)
{
if(vis[u]) return;
vis[u] = ;
for(int i=last[u];i!=-;i=G2[i].next)
{
int v = G2[i].v;
dfs(v);
if((nR[v] < nR[u]) || (nR[v] == nR[u] && nLen[v] < nLen[u]))
nR[u] = nR[v],nLen[u] = nLen[v];
}
} int main()
{
int n,m,i,j,len;
while(scanf("%d",&n)!=EOF)
{
now = ;
mp.clear();
tot = ;
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
for(i=;i<=n;i++)
{
cin>>ss[i];
len = ss[i].length();
int cntR = ;
for(j=;j<len;j++)
{
if(ss[i][j] >= 'A' && ss[i][j] <= 'Z')
ss[i][j] = ss[i][j]-'A'+'a';
if(ss[i][j] == 'r')
cntR++;
}
if(!mp[ss[i]])
mp[ss[i]] = ++now;
Len[mp[ss[i]]] = len;
minR[mp[ss[i]]] = cntR;
}
scanf("%d",&m);
string sa,sb;
for(i=;i<=m;i++)
{
sa = "", sb = "";
cin>>sa>>sb;
len = sa.length();
int cntR = ;
for(j=;j<len;j++)
{
if(sa[j] >= 'A' && sa[j] <= 'Z')
sa[j] = sa[j]-'A'+'a';
if(sa[j] == 'r')
cntR++;
}
if(!mp[sa])
mp[sa] = ++now;
int a = mp[sa];
Len[a] = len;
minR[a] = cntR; len = sb.length();
cntR = ;
for(j=;j<len;j++)
{
if(sb[j] >= 'A' && sb[j] <= 'Z')
sb[j] = sb[j]-'A'+'a';
if(sb[j] == 'r')
cntR++;
}
if(!mp[sb])
mp[sb] = ++now;
int b = mp[sb];
Len[b] = len;
minR[b] = cntR;
addedge(a,b);
}
memset(nR,INF,sizeof(nR)); //新图的点的minR,Len
memset(nLen,INF,sizeof(nLen));
Tarjan();
Build();
for(i=;i<=now;i++)
if(!vis[i])
dfs(i);
sumR = ,sumLen = ;
for(i=;i<=n;i++)
{
int u = bel[mp[ss[i]]];
sumR += nR[u];
sumLen += nLen[u];
}
printf("%I64d %I64d\n",sumR,sumLen);
}
return ;
}

还有一种做法就是反向建图,然后sort一下,优先从最优的开始dfs,最后就能得出结果,但是我不知道这样为什么一定正确,如果你知道,那么请评论告诉我吧:)

Codeforces Round #267 Div.2 D Fedor and Essay -- 强连通 DFS的更多相关文章

  1. 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 ...

  2. Codeforces Round #267 (Div. 2) B. Fedor and New Game【位运算/给你m+1个数让你判断所给数的二进制形式与第m+1个数不相同的位数是不是小于等于k,是的话就累计起来】

    After you had helped George and Alex to move in the dorm, they went to help their friend Fedor play ...

  3. Codeforces Round #267 (Div. 2) B. Fedor and New Game

    After you had helped George and Alex to move in the dorm, they went to help their friend Fedor play ...

  4. 01背包 Codeforces Round #267 (Div. 2) C. George and Job

    题目传送门 /* 题意:选择k个m长的区间,使得总和最大 01背包:dp[i][j] 表示在i的位置选或不选[i-m+1, i]这个区间,当它是第j个区间. 01背包思想,状态转移方程:dp[i][j ...

  5. Codeforces Round #267 (Div. 2) C. George and Job(DP)补题

    Codeforces Round #267 (Div. 2) C. George and Job题目链接请点击~ The new ITone 6 has been released recently ...

  6. Codeforces Round #267 (Div. 2)D(DFS+单词hash+简单DP)

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

  7. Codeforces Round #390 (Div. 2) D. Fedor and coupons(区间最大交集+优先队列)

    http://codeforces.com/contest/754/problem/D 题意: 给定几组区间,找k组区间,使得它们的公共交集最大. 思路: 在k组区间中,它们的公共交集=k组区间中右端 ...

  8. Codeforces Round #267 (Div. 2)

    A #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> ...

  9. Codeforces Round #267 (Div. 2) C. George and Job DP

                                                  C. George and Job   The new ITone 6 has been released ...

随机推荐

  1. 爱你.一万年>>数据库基础

    嗨!最近学习了一项新的技能,学习了数据库的知识,在这里抛砖引玉,给大家说说,望赐教!!>> 01.首先给大家谈谈为什么要使用数据库? 数据库可以看成是一个永久保存数据的仓库. 可以存储大量 ...

  2. js事件小记

    参考javascript编程全解  javascript高级程序设计 javascript经典实例 对事件的处理方式称为事件处理程序或事件侦听器 ,对于一个元素或事件,只能设定1个事件处理程序,却可以 ...

  3. cl_gui_cfw=>flush

       用法一:      REFRESH_TABLE_DISPLAY虽然刷新的界面,但是SAP GUI并不是实时更新,而是将更新的结果放在缓存中,手动调用CL_GUI_CFW=>FLUSH才能触 ...

  4. 解决Win10服务主机本地系统网络受限

    换成win10有一段时间了,界面风格比win7好看,但有部分程序还是不兼容,还好用虚拟机可以将就解决.但有一个问题一直困扰了我好久,今天终于解决了. 问题描述 在进程中,服务主机:本地系统(网络受限) ...

  5. ArcGIS补丁包下载

    http://zhihu.esrichina.com.cn/?/feature/patchdownload

  6. Engine中如何更改lyr文件数据源的相对路径

    以下是使用relativebase存储layerfile的代码,如果需要修改数据源只要修改ILayer即可: string folderpath = @E:相对路径; string layerfile ...

  7. 关于ApplicationPoolIdentity

    一直以来IIS中的网站默认都是以network service在运行,但是从IIS7开始,默认会以ApplicationPoolIdentity运行. 这个账户比较特殊,是一种虚拟帐户,你无法在计算机 ...

  8. 树莓派版的家用NAS服务器

    家里的文件越来越多,每个人的文件放得到处都是,需要的时候又找不到... 买个NAS服务器?太贵!太吵!太费电!... 好在我们有树莓派,自己动手,丰衣足食! 说做就做,主要分成以下三部分 加载双USB ...

  9. c语言的简易日历

    用c语言编写的简易日历,代码如下: #include <stdio.h> int main(int argc, const char * argv[]) { // insert code ...

  10. iOS8以后 UISearchController的用法

    查了不少资料,都不太全,自己查看了apple文档,写了一份代码: 如下(只是界面): 1. 声明属性 @property (nonatomic, strong) UISearchController ...