[1143] [CTSC2008]祭祀river(最大独立集 || 偏序集最大反链)

传送门

网上说这是偏序集最大反链,然而我实在不理解。

所以我换了一个思路,先用floyd,根据点的连通性连边,

问题就转换成了找出最多的点,使任意两个点之间不连边,也就是最大独立集。

——代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 
 5 const int MAXN = 101;
 6 int n, m, ans, cnt;
 7 int a[MAXN][MAXN], belong[MAXN], head[MAXN], to[MAXN << 6], next[MAXN << 6];
 8 bool vis[MAXN];
 9 
10 inline int read()
11 {
12     int x = 0;
13     char c = getchar();
14     for(; !isdigit(c); c = getchar());
15     for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + c - '0';
16     return x;
17 }
18 
19 inline bool find(int u)
20 {
21     int i, v;
22     for(i = head[u]; i ^ -1; i = next[i])
23     {
24         v = to[i];
25         if(!vis[v])
26         {
27             vis[v] = 1;
28             if(!belong[v] || find(belong[v]))
29             {
30                 belong[v] = u;
31                 return 1;
32             }
33         }
34     }
35     return 0;
36 }
37 
38 inline void add(int x, int y)
39 {
40     to[cnt] = y;
41     next[cnt] = head[x];
42     head[x] = cnt++;
43 }
44 
45 int main()
46 {
47     int i, j, k, x, y;
48     n = read();
49     m = read();
50     for(; m--;)
51     {
52         x = read();
53         y = read();
54         a[x][y] = 1;
55     }
56     for(k = 1; k <= n; k++)
57         for(i = 1; i <= n; i++)
58             for(j = 1; j <= n; j++)
59                 a[i][j] |= (a[i][k] && a[k][j]);
60     memset(head, -1, sizeof(head));
61     for(i = 1; i <= n; i++)
62         for(j = 1; j <= n; j++)
63             if(a[i][j])
64                 add(i, j);
65     ans = n;
66     for(i = 1; i <= n; i++)
67     {
68         memset(vis, 0, sizeof(vis));
69         ans -= find(i);
70     }
71     printf("%d
", ans);
72     return 0;
73 }
View Code
原文地址:https://www.cnblogs.com/zhenghaotian/p/6859664.html