首先强连通分量缩点。
然后A就是求有多少个如度为0的点,B就是求如度为0的点和出度为0的点的最大值。
特判强连通图的情况。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<stack> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 105; 21 const int maxm = 1e4 + 5; 22 inline ll read() 23 { 24 ll ans = 0; 25 char ch = getchar(), las = ' '; 26 while(!isdigit(ch)) las = ch, ch = getchar(); 27 while(isdigit(ch)) ans = ans * 10 + ch - '0', ch = getchar(); 28 if(las == '-') ans = -ans; 29 return ans; 30 } 31 inline void write(ll x) 32 { 33 if(x < 0) putchar('-'), x = -x; 34 if(x >= 10) write(x / 10); 35 putchar(x % 10 + '0'); 36 } 37 38 int n, m; 39 struct Edge 40 { 41 int to, nxt; 42 }e[maxm]; 43 int head[maxn], ecnt = 0; 44 void addEdge(int x, int y) 45 { 46 e[++ecnt].to = y; 47 e[ecnt].nxt = head[x]; 48 head[x] = ecnt; 49 } 50 51 stack<int> st; 52 bool in[maxn]; 53 int dfn[maxn], low[maxn], cnt = 0; 54 int col[maxn], ccol = 0; 55 void tarjan(int now) 56 { 57 dfn[now] = low[now] = ++cnt; 58 st.push(now); in[now] = 1; 59 for(int i = head[now]; i; i = e[i].nxt) 60 { 61 if(!dfn[e[i].to]) 62 { 63 tarjan(e[i].to); 64 low[now] = min(low[now], low[e[i].to]); 65 } 66 else if(in[e[i].to]) low[now] = min(low[now], dfn[e[i].to]); 67 } 68 if(dfn[now] == low[now]) 69 { 70 int x; ++ccol; 71 do 72 { 73 x = st.top(); st.pop(); 74 col[x] = ccol; 75 in[x] = 0; 76 }while(x != now); 77 } 78 } 79 80 int ru[maxn], chu[maxn]; 81 void newGraph(int now) 82 { 83 int u = col[now]; 84 for(int i = head[now]; i; i = e[i].nxt) 85 { 86 int v = col[e[i].to]; 87 if(u == v) continue; 88 ru[v]++; chu[u]++; 89 } 90 } 91 92 int main() 93 { 94 n = read(); 95 for(int i = 1; i <= n; ++i) 96 { 97 int x; 98 while(scanf("%d", &x) && x) addEdge(i, x); 99 } 100 for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i); 101 for(int i = 1; i <= n; ++i) newGraph(i); 102 if(ccol == 1) {printf("1 0 "); return 0;} 103 int cnt1 = 0, cnt2 = 0; 104 for(int i = 1; i <= ccol; ++i) cnt1 += (ru[i] == 0), cnt2 += (chu[i] == 0); 105 write(cnt1); enter; write(max(cnt1, cnt2)); enter; 106 return 0; 107 } 108 h