[USACO5.3]校园网Network of Schools

嘟嘟嘟

首先强连通分量缩点。

然后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
View Code
原文地址:https://www.cnblogs.com/mrclr/p/9758693.html