Equivalent sets
Time limit:12000/4000 MS (java/others) Memory limit:104857/104857 K (java/others)
Total submission (s): 3568 Accepted Submission (s): 1235
Problem Descriptionto prove-sets A and B are equivalent, we can first prove a was a subset of B, and then prove B is a Subset of A, so-finally we got that these and sets are equivalent.
You be to prove N sets be equivalent, using the method above:in each step can prove a set X is a subset of another Set Y, and there is also some sets that is already proven to being subsets of some other sets.
Now, want to know the minimum steps needed to get the problem proved.
Inputthe input file contains multiple test cases, in each case, the first line contains both integers N <= 20000 and M & lt;= 50000.
Next M lines, each line contains the integers x, Y, means set X in a subset of set Y.
Outputfor, output a single integer:the minimum steps needed.
Sample Input4 03 21 21 3
Sample Output42
HintCase 2:first prove set 2 are a subset of Set 1 and then prove set 3 is a subset of Set 1. Test instructions: The graph of the N-point M-edge, asking at least how many edges to connect the graph strongly. Solving: The degree and the degree of each SCC, and then the number of in and out of the degree of 0 in and out, take in and out of the larger one; because the degree or the degree of 0 proves that the SCC is not connected to another SCC and needs to be connected by an edge, which is the edge to join, Also because an SCC may be connected to more than one SCC, that is, only considering the degree of or only considering the degree of inaccuracy
#include <stdio.h> #include <string.h> #include <algorithm> #include <stack> #include < vector> #define MAX 50010#define INF 0x3f3f3fusing namespace Std;int n,m;int ans,head[max];int low[max],dfn[max];int Instack[max],sccno[max];vector<int>newmap[max];vector<int>scc[max];int Scccnt,dfsclock;int In[MAX], out[max];stack<int>s;struct node {int beg,end,next;} Edge[max];void init () {Ans=0;memset (head,-1,sizeof (Head));} void Add (int beg,int end) {edge[ans].beg=beg;edge[ans].end=end;edge[ans].next=head[beg];head[beg]=ans++;} void Getmap () {int I,a,b;while (m--) {scanf ("%d%d", &a,&b), add (A, b);}} void Tarjan (int u) {int V,i,j;s.push (u); instack[u]=1;low[u]=dfn[u]=++dfsclock;for (I=head[u];i!=-1;i=edge[i].next) { V=edge[i].end;if (!dfn[v]) {Tarjan (v); Low[u]=min (Low[u],low[v]);} else if (Instack[v]) low[u]=min (Low[u],dfn[v]);} if (Low[u]==dfn[u]) {scccnt++;while (1) {v=s.top (); S.pop (); instack[v]=0;sccno[v]=scccnt;if (v==u) Break;}}} void Find (int l,int r) {memset (low,0,sizeof (low) memset (dfn,0,sizeof (DFN)); Memset (Instack,0,sizeof (Instack)); Memset (Sccno,0,sizeof (SCCNO));d fsclock=scccnt =0;for (int i=l;i<=r;i++) {if (!dfn[i]) Tarjan (i);}} void Suodian () {int i;for (i=1;i<=scccnt;i++) {newmap[i].clear (); in[i]=0;out[i]=0;} for (i=0;i<ans;i++) {int u=sccno[edge[i].beg];int v=sccno[edge[i].end];if (u!=v) {newmap[u].push_back (v); in[v]++ ; out[u]++;}}} void Solve () {int i,j;if (scccnt==1) {printf ("0\n"); return;} Else{int minn=0;int maxx=0;for (i=1;i<=scccnt;i++) {if (!in[i]) minn++;if (!out[i]) maxx++;} printf ("%d\n", Max (Minn,maxx));}} int main () {while (scanf ("%d%d", &n,&m)!=eof) {init (); Getmap (); find (1,n); Suodian (); Solve ();} return 0;}
Hdoj 3836 equivalent Sets "scc&& indent" "to find a minimum number of edges to make the graph strong"