您的位置:首页 > 其它

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

2017-05-16 08:34 417 查看

传送门

 

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

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

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

 

——代码

#include <cstdio>
#include <cstring>
#include <iostream>

const int MAXN = 101;
int n, m, ans, cnt;
int a[MAXN][MAXN], belong[MAXN], head[MAXN], to[MAXN << 6], next[MAXN << 6];
bool vis[MAXN];

inline int read()
{
int x = 0;
char c = getchar();
for(; !isdigit(c); c = getchar());
for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + c - '0';
return x;
}

inline bool find(int u)
{
int i, v;
for(i = head[u]; i ^ -1; i = next[i])
{
v = to[i];
if(!vis[v])
{
vis[v] = 1;
if(!belong[v] || find(belong[v]))
{
belong[v] = u;
return 1;
}
}
}
return 0;
}

inline void add(int x, int y)
{
to[cnt] = y;
next[cnt] = head[x];
head[x] = cnt++;
}

int main()
{
int i, j, k, x, y;
n = read();
m = read();
for(; m--;)
{
x = read();
y = read();
a[x][y] = 1;
}
for(k = 1; k <= n; k++)
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
a[i][j] |= (a[i][k] && a[k][j]);
memset(head, -1, sizeof(head));
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
if(a[i][j])
add(i, j);
ans = n;
for(i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
ans -= find(i);
}
printf("%d\n", ans);
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: