Both questions are water questions. 1236 the first question is the number of points with a degree of 0 after the contraction point. The second question is how many sides are added to make the full graph strongly connected. This is a classic practice, read white books for details
Poj2186 is the number of points (the number of points in SCC) included in the unique vertex with a contraction degree of 0)
//poj1236
#include<iostream>
#include<cstdio>
#include<string.h>
#define maxn 6000
int now=0,next[maxn],head[maxn],point[maxn],num=0,dfn[maxn],low[maxn],instack[maxn];
int stack[maxn],belong[maxn],top,count,in[maxn],out[maxn];
int min(int a,int b)
{
if (a<b)return a;else return b;
}
int max(int a,int b)
{
if (a>b)return a;else return b;
}
void add(int x,int y)
{
next[++now]=head[x];
head[x]=now;
point[now]=y;
}
void tarjan(int k)
{
int u;
instack[k]=true;
dfn[k]=low[k]=++num;stack[++top]=k;
for(int i=head[k];i!=0;i=next[i])
{
u=point[i];
if (dfn[u]==0)
{
tarjan(u);
low[k]=min(low[k],low[u]);
}
else if (instack[u])low[k]=min(dfn[u],low[k]);
}
if (low[k]==dfn[k])
{
++count;
do
{
u=stack[top--];
instack[u]=false;
belong[u]=count;
}while(u!=k);
}
}
int main()
{
int n,t;
scanf("%d",&n);
for(int i=1;i<=n;i++)while (1)
{
scanf("%d",&t);
if (t==0)break;
else add(i,t);
}
for(int i=1;i<=n;i++)if (dfn[i]==0)tarjan(i);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j!=0;j=next[j])
{
int u=point[j];
if (belong[i]!=belong[u])
{
out[belong[i]]++;
in[belong[u]]++;
}
}
}
int countout=0,countin=0;
for(int i=1;i<=count;i++)
{
if (out[i]==0)countout++;
if (in[i]==0)countin++;
}
if (count==1)printf("1\n0\n");
else printf("%d\n%d\n",countin,max(countout,countin));
return 0;
}
// Poj2186
# Include <iostream>
# Include <cstdio>
# Include <string. h>
# Define maxn50010
Using namespace STD;
Intnow = 0, next [maxn], head [maxn], point [maxn], num = 0, dfn [maxn], low [maxn], instack [maxn];
Int stack [maxn], belong [maxn], top, Count, out [maxn], p [maxn];
Void add (int x, int y)
{
Next [++ now] = head [x];
Head [x] = now;
Point [now] = y;
}
Void Tarjan (int K)
{
Instack [k] = 1;
Stack [++ top] = K;
Low [k] = dfn [k] = ++ num;
Int U;
For (INTI = head [k]; I! = 0; I = next [I])
{
U = point [I];
If (dfn [u] = 0)
{
Tarjan (U );
Low [k] = min (low [u], low [k]);
}
Else if (instack [u] = 1) low [k] = min (dfn [u], low [k]);
}
If (low [k] = dfn [k])
{
++ Count;
Do
{
U = stack [top --];
Instack [u] = 0;
Belong [u] = count;
P [count] ++;
} While (u! = K );
}
}
Int main ()
{
Int n, m, X, Y, ANS = 0;
Scanf ("% d", & N, & M );
For (INT I = 1; I <= m; I ++)
{
Scanf ("% d", & X, & Y );
Add (x, y );
}
For (INT I = 1; I <= N; I ++)
If (dfn [I] = 0) Tarjan (I );
For (INT I = 1; I <= N; I ++)
{
For (Int J = head [I]; J! = 0; j = next [J])
{
Int u = point [J];
If (belong [I]! = Belong [u]) out [belong [I] ++;
}
}
Int flag = 0;
For (INTI = 1; I <= count; I ++)
{
If (ANS! = 0 & out [I] = 0) {flag = 1; break ;}
If (out [I] = 0) ans = P [I];
}
If (flag = 0) printf ("% d \ n", ANS); else printf ("0 \ n ");
Return 0;
}
Tarjan poj1236 poj2186 of SCC