Question link:
Question:
Given n words.
There are m Replacement Methods below, and the words on the Left can become words on the right.
After any replacement, the number of the last letter R is the minimum, and the total length of the word is the minimum if R is the least.
Number and Word Length of the output letter R.
Ideas:
If a word has two parameters, M replacement rules can be used as Directed Graphs of M points.
The end point of some words will be determined, so we will reverse the BFS.
To prevent vertices from being updated repeatedly, place the weights of each vertex in the stack in an order and then 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 300005int 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