https://vjudge.net/problem/POJ-1236
思路: 一个DAG上从入度为0的点出发一定可以走遍当前DAG, 所以第一问输出入度为0的点的个数
对于一个DAG, 入度为0的一定是起点, 出度为0的一定是终点. 仔细思考一下, 如果只有一个起点显然应该加一条边, 如果只有一个终点也应该加一条边, 都可以使图变为一个强连通图
我们对起点或终点哪个更大, 我们就应该加对应的边数,同时要特判只有一个SCC的情况图片说明

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=105,M=1e4+5;
int ver[M],Next[M],head[N],dfn[N],low[N];
int stack[N],ins[N],c[N],in[N],out[N];
int n,tot,num,top,cnt;
void add(int x,int y){
    ver[++tot]=y,Next[tot]=head[x],head[x]=tot;
}
void tarjan(int x){
    dfn[x]=low[x]=++num;
    stack[++top]=x,ins[x]=1;
    for(int i=head[x];i;i=Next[i])
        if(!dfn[ver[i]]){
            tarjan(ver[i]);
            low[x]=min(low[x],low[ver[i]]);
        }
        else if(ins[ver[i]])
            low[x]=min(low[x],dfn[ver[i]]);
    if(dfn[x]==low[x]){
        cnt++;
        int y;
        do{
            y=stack[top--],ins[y]=0;
            c[y]=cnt;
        }while(x!=y);
    }
}
int main(){
    scanf("%d",&n);
    for(int x=1;x<=n;x++){
        int y;
        while(~scanf("%d",&y)&&y)    add(x,y);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])    tarjan(i);
    for(int x=1;x<=n;x++)
        for(int i=head[x];i;i=Next[i]){
            int y=ver[i];
            if(c[x]==c[y])    continue;
            in[c[y]]++,out[c[x]]++;
        }
    int p=0,q=0;
    for(int i=1;i<=cnt;i++){
        if(!in[i])    p++;
        if(!out[i])    q++;
    }
    printf("%d\n",p);
    if(cnt==1)    printf("0");
    else        printf("%d",max(q,p));
    return 0;
}