Test instructions: There are n individuals, m relationships, relationships are these two people before a person can compare with the latter one. Then ask you how many groups I have at least can make the people in this group can not compare.
will only be strong link to shrink point, akzent do not know how to do, think for one hours, on-line a look, but also to the partial order set of things, there is a called Dilworth theorem of things. Theorem 1 (x,≤) is a finite partial order set and makes R the size of its largest chain. Then x can be divided into R but no less anti-chain.
The duality theorem is called the Dilworth theorem:
Theorem 2 (x,≤) is a finite partial order set and makes m the largest size of the inverse chain. Then x can be divided into M-but no less chain.
And then we used the theorem 1.
That is, we directly seek to compare the largest chain size. First strong unicom contraction point, and then use the topological sequence BFS side, find the longest chain, OK. O (︶^︶) O Alas, the feeling is to test this theorem.
#include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include < Queue> #include <algorithm>using namespace std;const int maxn = 100010; Point const int MAXM = 300010; Edge number struct edge{int to, next;} edge[maxm];int head[maxn],tot;int LOW[MAXN],DFN[MAXN],STACK[MAXN],BELONG[MAXN]; The value of the belong array is 1~sccint Index,top;int SCC; The number of strongly connected components bool Instack[maxn];int NUM[MAXN]; Each strong connected component contains the number of points, the array number 1~scc//num array is not necessarily required, the actual situation int Dis[maxn];int in[maxn];vector<int>g[maxn];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);} void work () {memset (dis,0,sizeof (dis)); queue<int>q; for (int i=1;i<=scc;i++) {if (in[i]==0) {Q.push (i);d is[i]=num[i];} } while (!q.empty ()) {int U=q.front (); Q.pop (); int V; for (int i=0;i<g[u].size (); i++) {v=g[u][i]; Dis[v]=max (Dis[u]+num[v],dis[v]); in[v]--; if (in[v]==0) Q.push (v); }} int ans=0; for (int i=1;i<=scc;i++) {Ans=max (ans,dis[i]); } printf ("%d\n", ans);} void init () {tot = 0; Memset (Head,-1, sizeof (head)); memset (In,0,sizeof (in)); int main () {int n,m,a,b; while (~SCANF ("%d%d", &n,&m)) {init (); for (int i=1;i<=m;i++) {scanf ("%d%d", &a,&b); Addedge (A, b); } solve (n); for (int i=1;i<=scc;i++) {g[i].clear (); } for (int i=1;i<=n;i++) {for (int j=head[i];j!=-1;j=edge[j].next) {int v=ed ge[j].to; if (Belong[i]!=belong[v]) {in[belong[v]]++; G[belong[i]].push_back (Belong[v]); }}} work (); }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
ZOJ 3795 Grouping The maximum chain size of the strong link reduction + topological order + partial sequence set