4269. 【NOIP2015模拟10.27】挑竹签
(File IO): input:mikado.in output:mikado.out
Time Limits: 1000 ms Memory Limits: 131072 KB Detailed Limits
Goto ProblemSet做法:不难发现,对于a 压住 b 这种情况,可以由 a 向 b 连一条边,然后拓扑排序找最长链就好了。
代码如下:
View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <string> 5 #define N 1000007 6 using namespace std; 7 struct edge 8 { 9 int to, next; 10 }e[N * 2]; 11 int rd[N], n, m, ls[N], tot, list[N]; 12 bool v[N]; 13 14 int read() 15 { 16 int s = 0; 17 char c = getchar(); 18 while (c < '0' || c > '9') c = getchar(); 19 while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar(); 20 return s; 21 } 22 23 int main() 24 { 25 freopen("mikado.in", "r", stdin); 26 freopen("mikado.out", "w", stdout); 27 n = read(), m = read(); 28 for (int i = 1; i <= m; i++) 29 { 30 int x, y; 31 x = read(), y = read(); 32 rd[y]++; 33 e[++tot].to = y; 34 e[tot].next = ls[x]; 35 ls[x] = tot; 36 } 37 int head = 0, tail = 0; 38 for (int i = 1; i <= n; i++) 39 if (rd[i] == 0) list[++tail] = i, v[i] = 1; 40 while (head <= tail) 41 { 42 head++; 43 for (int i = ls[list[head]]; i; i = e[i].next) 44 { 45 rd[e[i].to]--; 46 if (rd[e[i].to] == 0 && !v[e[i].to]) 47 { 48 v[e[i].to] = 1; 49 list[++tail] = e[i].to; 50 } 51 } 52 } 53 printf("%d", tail); 54 }