Great group. That is, to find a maximum point set, so that any two vertices in the vertex set U, V exists at least U-> V, or V-> U path.
In this way, find all the connected components, and then the entire graph becomes a non-cycle graph, reducing the original several vertices with the point weight as the points of the component. This is equivalent to finding the path with the largest weight. Because there is no ring, this can be solved by topological sorting and then DP.
Here we will focus on the pitfalls we have encountered.
D [cur] = low [cur] = ++ dfsclock; it must not be d [cur] = low [cur] = d [fa] + 1;
The latter is wrong.
I thought for a long time before I found out the problem.
Assume that we use the d [fa] + 1 method to mark, when the path is 1-> 2-> 3, when the recursive return is low [1] = 1, low [2] = 1, low [3] = 2. When we access 4 points at this time, low [4] can only be 2 at least. From the program perspective, it is considered that 4 is a separate strong Unicom component, which is not correct.
However, if we mark using the + + dfsclock method, low [1] = 1, low [2] = 1, low [3] = 2, low [4] = 2, but at this time d [4] = 4, you can determine that it is not a separate strongly connected component. It is mainly through ++ dfsclock to determine whether it has been accessed before. This is irrelevant to the source point distance. Pay special attention to it.
Summon code:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define maxn 1010#define maxm 202000using namespace std;int first[maxn],next[maxm],to[maxm],edge;int low[maxn],d[maxn],belong[maxn],scc;int U[maxm],V[maxm],stack[maxn],top;int f[maxn],sum[maxn],Q[maxn];int n,m,T,ans,dfsclock;bool cmp(int q1,int q2){ return d[q1]>d[q2];}void _init(){ dfsclock=ans=top=scc=0,edge=-1; for (int i=1; i<=n; i++) first[i]=-1,low[i]=d[i]=belong[i]=0;}void addedge(int uu,int vv){ edge++; to[edge]=vv,next[edge]=first[uu],first[uu]=edge;}void dfs(int cur,int fa){ d[cur]=low[cur]=++dfsclock; stack[++top]=cur; for (int i=first[cur]; i!=-1; i=next[i]) { if (belong[to[i]]) continue; if (!d[to[i]]) dfs(to[i],cur); low[cur]=min(low[cur],low[to[i]]); } if (low[cur]>=d[cur]) for (scc++,f[scc]=0;;) { belong[stack[top--]]=scc; f[scc]++; if (stack[top+1]==cur) break; }}int get(int x){ if (d[x]!=0) return d[x]; if (first[x]==-1) return d[x]=1; d[x]=0; for (int i=first[x]; i!=-1; i=next[i]) d[x]=max(d[x],get(to[i])+1); return d[x];}int main(){ scanf("%d",&T); while (T--) { scanf("%d%d",&n,&m); _init(); for (int i=1; i<=m; i++) { scanf("%d%d",&U[i],&V[i]); addedge(U[i],V[i]); } for (int i=1; i<=n; i++) if (!d[i]) dfs(i,0); edge=-1; for (int i=1; i<=scc; i++) first[i]=-1,d[i]=0; for (int i=1; i<=m; i++) if (belong[U[i]]!=belong[V[i]]) addedge(belong[U[i]],belong[V[i]]); for (int i=1; i<=scc; i++) { Q[i]=i,sum[i]=0; if (!d[i]) d[i]=get(i); } sort(Q+1,Q+1+scc,cmp); for (int i=1; i<=scc; i++) { sum[Q[i]]+=f[Q[i]]; ans=max(ans,sum[Q[i]]); for (int j=first[Q[i]]; j!=-1; j=next[j]) sum[to[j]]=max(sum[to[j]],sum[Q[i]]); } printf("%d\n",ans); } return 0;}