https://www.luogu.com.cn/problem/P10287

 1.a的范围就是一个提示点,提示我们用价值遍历

2.按经过节点先后顺序,所以在bfs实现拓扑序的实现dp

3.重点,不是入度为0的时候才dp,是因为可能是一条环

hack数据:

6 6
1 2 3 2 1 3
1 2
2 3
3 6
3 4
4 5
5 3

正确答案应该是3;

若在入度为0的时候ma=2,因为没考虑3

#include<bits/stdc++.h>
#include<string>
using namespace std;
#define N 100011
typedef long long ll;
typedef pair<int,int> pii;
queue<int> q;
vector<int> mp[N];
int d[N];
int n,m;
int dp[N][12];
vector<int> an;
int in[N];
int ma=0;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
	cin>>d[i];
	dp[i][d[i]]=1;
}
an.push_back(0);
for(int i=0;i<m;i++)
{
	int x,y;
	cin>>x>>y;
	in[y]++;
	mp[x].push_back(y);
}
for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
while(q.size())
{
	int t=q.front();
	q.pop();
	for(int i=0;i<mp[t].size();i++)
	{
		int v=mp[t][i];
		in[v]--;
		if(!in[v])
		 {
			q.push(v);	 
		 }
		 ///不是入度为0的点也参与 
		for(int j=1;j<=d[v];j++)///前i件,最后(即最大价值)为j的dp 
			dp[v][d[v]]=max(dp[t][j]+1,dp[v][d[v]]);///可以被d[v]更新 
		for(int j=1;j<=10;j++)///更新全部价值在i当前的最大 
			dp[v][j]=max(dp[v][j],dp[t][j]);
	}
}
///遍历全部寻找最大 
for(int i=1;i<=n;i++) for(int j=1;j<=10;j++) ma=max(dp[i][j],ma);
cout<<ma;
return 0;
}

Logo

集算法之大成!助力oier实现梦想!

更多推荐