D. Substring
阿新 • • 發佈:2018-02-01
set amp har turn ack force http esp 相同
D. Substring
題意:
給你一個有向圖,然後給你一串字符串第i個點的值為第i個字符,然後給你m條有向邊,從中找一條路徑然後這條路徑中點的值相同的個數的最大值,如果圖有環輸出-1。
思路:
拓撲排序+dp
我們需要找到一條路徑的開頭,用拓撲排序即可,然後每個點維護26個字母在到當前點的路徑上出現最大值即可,復雜度O(n*26)。
題鏈
代碼:
#include<bits/stdc++.h> using namespace std; int dp[300005][26]; class Solution { public: int n,m; char str[300005]; int cnt[300005]; vector<int>vec[300005]; queue<int>que; map<pair<int,int>,int>my; Solution() { memset(str,0,sizeof(str)); memset(cnt,0,sizeof(cnt)); for(int i = 0; i < 300005; i++) vec[i].clear(); while(!que.empty()) { que.pop(); } } void in_put() { scanf("%d %d",&n,&m); scanf("%s",str); for(int i = 0; i < m; i++) { int x,y; scanf("%d %d",&x,&y); if(!my.count(make_pair(x,y))) { my[make_pair(x,y)] = 1; cnt[y]++; vec[x].push_back(y); } } } int TUPU() { int maxx = -1; int cn = 0; for(int i = 1; i <= n; i++) { if(cnt[i] == 0) { que.push(i); dp[i][str[i-1] - 'a'] = 1; maxx = 1; cn++; } } while(!que.empty()) { int id = que.front(); que.pop(); for(int i = 0; i < vec[id].size(); i++) { int ic = vec[id][i]; for(int j = 0; j < 26; j++) { if(j == str[ic - 1] - 'a') dp[ic][j] = max(dp[ic][j],dp[id][j] + 1); else dp[ic][j] = max(dp[ic][j],dp[id][j]); // printf("%d %d %d\n",id,maxx,ic); maxx = max(dp[ic][j],maxx); } cnt[ic]--; if(cnt[ic] == 0) cn++,que.push(ic); } } if(cn == n) return maxx; return -1; } }; int main(void) { Solution A; A.in_put(); cout<<A.TUPU(); return 0; }
D. Substring