codeforce #460 div2 D. Substring

D. Substring
time limit per test
3 seconds
You are given a graph with n nodes and m directed edges. One lowercase letter is assigned to each node. We define a path's value as the number of the most frequently occurring letter. For example, if letters on a path are "abaca", then the value of that path is 3. Your task is find a path whose value is the largest.

Input
The first line contains two positive integers n, m (1 ≤ n, m ≤ 300 000), denoting that the graph has n nodes and m directed edges.

The second line contains a string s with only lowercase English letters. The i-th character is the letter assigned to the i-th node.

Then m lines follow. Each line contains two integers x, y (1 ≤ x, y ≤ n), describing a directed edge from x to y. Note that x can be equal to y and there can be multiple edges between x and y. Also the graph can be not connected.

Output
Output a single line with a single integer denoting the largest value. If the value can be arbitrarily large, output -1 instead.

题意

        给定一个有向图,n个顶点,m条边,每个顶点有一个小写字母。每条路可由经过的结点组成的字符串表示,路的值由该字符串中出现次数最多的字母的出现次数。求图中所有路最大的值,如果值可以无限大,即存在环路,则输出-1.

 题解

       从一个入度不为0的点跑的话,不如从他的父节点开始跑,长度更长,以此类推,得到从入度为0的点开始跑。而且该图为有向图,有自环和平行边,用拓扑排序也好判断,所以用拓扑排序。设a[N][26],第一维是编号,第二维是当前字符出现的最大频率。用父节点的值更新当前节点的值。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define check system("pause")
#define all(x) (x).begin(),(x).end()
#define de(a) cout<<#a<<" = "<<a<<endl
#define dd(a) cout<<#a<<" = "<<a<<" "
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lowbit(a) ((a)&-(a))
#define INF 0x3f3f3f3f
const ll mod = 1e9+7;
const int N = 3e5+20;
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define mes(p,b) memset(p,b,sizeof(p))
#define sz(x) int(x.size())
int a[N][26],n,m,s[N],in[N];vi to[N];
int main()
{
  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  cin>>n>>m;
  rep(i,1,n){
      char c;
      cin>>c;
      s[i]=c-'a';
  } 
  rep(i,1,m){
      int x,y;
      cin>>x>>y;
      to[x].pb(y);
      in[y]++;
  }
  queue<int> q;
  rep(i,1,n) if(in[i]==0) q.push(i);
  int cnt=0,ans=0;
  while(!q.empty()){
      cnt++;
      int t=q.front();q.pop();
      a[t][s[t]]++;
      ans=max(a[t][s[t]],ans);
      for(auto i:to[t]){
          rep(j,0,25){
              a[i][j]=max(a[i][j],a[t][j]);
              ans=max(ans,a[i][j]);
          }
        if(--in[i]==0) q.push(i);
      }
  }
  if(cnt!=n) cout<<-1;
  else cout<<ans;
  return 0;
}
原文地址:https://www.cnblogs.com/FZUlh/p/12288335.html