problem B:the Largest clique
Given a directed graph G, consider the following transformation. First, create a new graph T (g) to has the same vertex set as G. Create a directed edge between the vertices u and V in t ( G) If and only if there are a path between U and V in G so follows the directed edges only in the forward direction. This graph T (g) is often called the transitive closure of G.
We define a clique in a directed graph as a set of vertices u such so for any of the vertices U and V in U, there is a dire CTED edge either from U-V or from V to U (or both). The size of a clique is the number of vertices in the clique.
The number of cases is given on the first line of input. Each test case describes a graph G. It begins with a line of between integers n and m, where 0≤n≤1000 is the number of vertices of G and 0≤m≤50,000 are the Number of directed edges of G. The vertices of G is numbered from 1 to N. The following m lines contain the distinct integers u and v between 1 and N which define a directed edge from U to V in G.
For each test case, output a single integer so is the size of the largest clique in T (G). Sample Input
1
5 5
1 2
2 3
3 1
4 1
5 2
Output for sample input
4
Zachary Friggstad
The SCC graph is obtained after the strongly connected component is shrunk, and the right of each SCC node equals his number of nodes, because the SCC is a DAG graph, so it can be solved by DP.
#include <cstdio> #include <cstring> #include <queue> #include <vector> #include <algorithm
> #include <stack> using namespace std;
const int MAXN = 1000 + 5;
Vector<int> G[MAXN];
int PRE[MAXN], LOWLINK[MAXN], SCCNO[MAXN], Dfs_clock, scc_cnt;
Stack<int> S;
void Dfs (int u) {pre[u] = lowlink[u] = ++dfs_clock;
S.push (U);
for (int i = 0; i < g[u].size (); i++) {int v = g[u][i];
if (!pre[v]) {DFS (v);
Lowlink[u] = min (Lowlink[u], lowlink[v]);
} else if (!sccno[v]) {Lowlink[u] = min (Lowlink[u], pre[v]);
}} if (lowlink[u] = = Pre[u]) {scc_cnt++; for (;;) {int x = S.top ();
S.pop ();
SCCNO[X] = scc_cnt;
if (x = = u) break;
}}} void find_scc (int n) {dfs_clock = scc_cnt = 0;
memset (sccno, 0, sizeof (SCCNO));
memset (pre, 0, sizeof (pre));
for (int i = 0; i < n; i++) if (!pre[i]) DFS (i);
} vector<int> MAP[MAXN];
int VAL[MAXN];
int DP[MAXN];
int find (int x) { if (map[x].size () = = 0) return dp[x] = val[x];
if (Dp[x]) return dp[x];
int Max = 0;
for (int i = 0;i < Map[x].size (); i++) max = max (Max,find (Map[x][i]));
return dp[x] = val[x] + Max;
} int main () {int t,n,m;
scanf ("%d", &t);
while (t--) {memset (Val,0,sizeof (Val)); for (int i = 0;i < maxn;i++) {g[i].clear (); Map[i].clear ();
} memset (Dp,0,sizeof (DP));
scanf ("%d%d", &n,&m);
while (m--) {int u,v;
scanf ("%d%d", &u,&v); u--;v--;
if (U = = v) continue;
G[u].push_back (v);
} FIND_SCC (n);
for (int u = 0;u < n;u++) {val[sccno[u]]++;
for (int j = 0;j < G[u].size (); j + +) {int v = g[u][j];
if (sccno[u]! = Sccno[v]) map[sccno[u]].push_back (Sccno[v]);
}} int ans = 0;
for (int i = 0;i <= scc_cnt;i++) ans = max (Ans,find (i));
printf ("%d\n", ans);
} return 0;
}