Codeforces Round #786 (Div. 3)-G
题目
解题思路
通过分析知道,处于第一个的点必须满足出度为2以上,最后一个点的入度必须在2以上。
中间的每个点都需要出入度均在2以上。
于是考虑dfs搜索来从每个可能的顶点出发,遍历所有可以达到的位置加以比较。
中间注意使用记忆化搜索,可以大大节约时间
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
vector<int> in;
vector<int> out;
vector<vector<int>> e;
vector<int> dp;
const int INF=1e9;
int cal(int v)
{
if (dp[v]!=-1)
return dp[v];//记忆化搜索
if (in[v]>=2&&out[v]>=2)
{
//可以是其中的点
dp[v]=1;
for (int u:e[v])
{
dp[v]=max(dp[v],cal(u)+1);
}
}
else if(in[v]>=2)
{
dp[v]=1;//可以作为结尾
}
else
dp[v]=-INF;
return dp[v];
}
int main()
{
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
in.resize(n);
out.resize(n);
e.resize(n);
for (int i=0;i<m;i++)
{
int s,d;
cin>>s>>d;
s--;
d--;
//注意下标统一
e[s].push_back(d);
in[d]++; //入度
out[s]++;//出度
}
dp.resize(n,-1);//赋初值
int ans=1;//结果
for (int i=0;i<n;i++)
{
//从每个边开始遍历
if (out[i]>=2)//说明可以是开头
{
for (int u:e[i])
ans=max(ans,cal(u)+1);
}
}
cout<<ans<<endl;
system("pause");
return 0;
}