版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GYH0730/article/details/82318474
两道类型一样的套路题,附上zoj的代码,另外一道只需改一改数据范围就行了
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int MAXM = 300005;
//-----------------------有向图找强连通分量------------------------
struct Edge
{
int to,Next;
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
int Index,top;
int scc;
bool Instack[MAXN];
int num[MAXN];
void init()
{
tot = 0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].Next = head[u];
head[u] = tot++;
}
void Tarjan(int u)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; i != -1; i = edge[i].Next) {
v = edge[i].to;
if(!DFN[v]) {
Tarjan(v);
if(Low[u] > Low[v]) Low[u] = Low[v];
}
else if(Instack[v] && Low[u] > DFN[v])
Low[u] = DFN[v];
}
if(Low[u] == DFN[u]) {
scc++;
do {
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc;
num[scc]++;
}
while(v != u);
}
}
void solve(int N)
{
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(num,0,sizeof(num));
Index = scc = top = 0;
for(int i = 1; i <= N; i++) {
if(!DFN[i]) {
Tarjan(i);
}
}
}
//-----------------------有向图找强连通分量------------------------
//-----------------------DAG最长路---------------------------------
int dp[MAXN];
vector<int> G[MAXN];
int DP(int u)
{
int& ans = dp[u];
if(ans >= 0) return ans;
ans = num[u];
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
ans = max(ans,DP(v) + num[u]);
}
return ans;
}
//-----------------------DAG最长路---------------------------------
int main(void)
{
int n,m,u,v,ans;
while(scanf("%d %d",&n,&m) != EOF) {
init();
while(m--) {
scanf("%d %d",&u,&v);
addedge(u,v);
}
solve(n);
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 1; i <= n; i++) {
u = Belong[i];
for(int j = head[i]; j != -1; j = edge[j].Next) {
v = Belong[edge[j].to];
if(u != v) G[u].push_back(v);
}
}
ans = 0;
memset(dp,-1,sizeof(dp));
for(int i = 1; i <= n; i++) {
ans = max(ans,DP(i));
}
printf("%d\n",ans);
}
return 0;
}
/*
1
5 5
1 2
2 3
3 1
4 1
5 2
*/