G. Remove Directed Edges
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a directed acyclic graph, consisting of nn vertices and mm edges. The vertices are numbered from 11 to nn. There are no multiple edges and self-loops.
Let invinv be the number of incoming edges (indegree) and outvoutv be the number of outgoing edges (outdegree) of vertex vv.
You are asked to remove some edges from the graph. Let the new degrees be in′vin′v and out′vout′v.
You are only allowed to remove the edges if the following conditions hold for every vertex vv:
- in′v<invin′v<inv or in′v=inv=0in′v=inv=0;
- out′v<outvout′v<outv or out′v=outv=0out′v=outv=0.
Let's call a set of vertices SS cute if for each pair of vertices vv and uu (v≠uv≠u) such that v∈Sv∈S and u∈Su∈S, there exists a path either from vv to uu or from uu to vv over the non-removed edges.
What is the maximum possible size of a cute set SS after you remove some edges from the graph and both indegrees and outdegrees of all vertices either decrease or remain equal to 00?
Input
The first line contains two integers nn and mm (1≤n≤2⋅1051≤n≤2⋅105; 0≤m≤2⋅1050≤m≤2⋅105) — the number of vertices and the number of edges of the graph.
Each of the next mm lines contains two integers vv and uu (1≤v,u≤n1≤v,u≤n; v≠uv≠u) — the description of an edge.
The given edges form a valid directed acyclic graph. There are no multiple edges.
Output
Print a single integer — the maximum possible size of a cute set SS after you remove some edges from the graph and both indegrees and outdegrees of all vertices either decrease or remain equal to 00.
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const int N=2e5+5;
int h[N],e[N],ne[N],idx;
int din[N],dout[N],d[N];
int q[N];
int dp[N];
int n,m;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void topsort()
{
int hh=0,tt=-1;
for(int i=1;i<=n;i++)
{
if(!d[i]) q[++tt]=i;
}
while(hh<=tt)
{
int now=q[hh++];
for(int i=h[now];~i;i=ne[i])
{
int to=e[i];
if(dout[now]>=2&&din[to]>=2) dp[to]=max(dp[to],dp[now]+1);
if(--d[to]==0) q[++tt]=to;
}
}
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++) dp[i]=1;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
add(a,b);
din[b]++,dout[a]++,d[b]++;
}
topsort();
int res=0;
for(int i=1;i<=n;i++) res=max(res,dp[i]);
cout<<res<<endl;
}