Network of Schools(POJ1326+有向图进行缩点)
题目链接:http://poj.org/problem?id=1236
题目:
题意:对于n个学校,对于一个系统传给某个学校,那么他会传给他得支援学校。从第二开始,每行给你多个数字,表示第i个学校可以支援这些学校,以0结尾。问你一个新软件至少要给多少个学校,如果任意传给某个学校都能传给其他学校需要建多少条支援关系。
思路:tarjan进行缩点,重新建图,对新建得有向无环图统计一下出度和入度,第一问答案就是入度为0的数量,第二问则是max(入度为0的个数,出度为0的个数)。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef pair<ll, ll> pll; 18 typedef pair<ll, int> pli; 19 typedef pair<int, ll> pil;; 20 typedef pair<int, int> pii; 21 typedef unsigned long long ull; 22 23 #define lson i<<1 24 #define rson i<<1|1 25 #define bug printf("*********\n"); 26 #define FIN freopen("D://code//in.txt", "r", stdin); 27 #define debug(x) cout<<"["<<x<<"]" <<endl; 28 #define IO ios::sync_with_stdio(false),cin.tie(0); 29 30 const double eps = 1e-8; 31 const int mod = 10007; 32 const int maxn = 100 + 7; 33 const double pi = acos(-1); 34 const int inf = 0x3f3f3f3f; 35 const ll INF = 0x3f3f3f3f3f3f3f; 36 37 int n, tot, x, cnt, num, top; 38 int head[maxn], c[maxn]; 39 int in[maxn], out[maxn], vis[maxn]; 40 int dfn[maxn], low[maxn], stc[maxn]; 41 42 void init() { 43 tot = cnt= num = top = 0; 44 memset(c, 0, sizeof(c)); 45 memset(in, 0, sizeof(in)); 46 memset(out, 0, sizeof(out)); 47 memset(vis, 0, sizeof(vis)); 48 memset(stc, 0, sizeof(stc)); 49 memset(dfn, 0, sizeof(dfn)); 50 memset(low, 0, sizeof(low)); 51 memset(head, -1, sizeof(head)); 52 } 53 54 struct edge { 55 int v, next; 56 }ed[maxn*maxn]; 57 58 void addedge(int u, int v) { 59 ed[tot].v = v; 60 ed[tot].next = head[u]; 61 head[u] = tot++; 62 } 63 64 void tarjan(int x) { 65 dfn[x] = low[x] = ++num; 66 stc[++top] = x, vis[x] = 1; 67 for(int i = head[x]; ~i; i = ed[i].next) { 68 int y = ed[i].v; 69 if(!dfn[y]) { 70 tarjan(y); 71 low[x] = min(low[x], low[y]); 72 } else if(vis[y]) { 73 low[x] = min(low[x], low[y]); 74 } 75 } 76 if(dfn[x] == low[x]) { 77 cnt++; int y; 78 do { 79 y = stc[top--]; vis[y] = 0; 80 c[y] = cnt; 81 }while(x != y); 82 } 83 } 84 85 int main() { 86 //FIN; 87 scanf("%d", &n); 88 init(); 89 for(int i = 1; i <= n; i++) { 90 while(1) { 91 scanf("%d", &x); 92 if(x == 0) break; 93 addedge(i, x); 94 } 95 } 96 for(int i = 1; i <= n; i++) { 97 if(!dfn[i]) { 98 tarjan(i); 99 } 100 } 101 for(int i = 1; i <= n; i++) { 102 for(int j = head[i]; ~j; j = ed[j].next) { 103 int y = ed[j].v; 104 if(c[i] == c[y]) continue; 105 out[c[i]]++; 106 in[c[y]]++; 107 } 108 } 109 if(cnt == 1) { 110 printf("1\n0\n"); 111 return 0; 112 } 113 int ans1 = 0, ans2 = 0; 114 for(int i = 1; i <= cnt; i++) { 115 if(in[i] == 0) ans1++; 116 if(out[i] == 0) ans2++; 117 } 118 printf("%d\n%d\n", ans1, max(ans1, ans2)); 119 return 0; 120 }
版权声明:本文允许转载,转载时请注明原博客链接,谢谢~