# [BZOJ 1143] [CTSC2008] 祭祀river 【最长反链】

### 代码

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MaxN = 100 + 5;

int n, m, Ans, Index;
int Used[MaxN * 2], Father[MaxN * 2];

bool OK[MaxN][MaxN];

struct Edge
{
int v;
Edge *Next;
} E[MaxN * MaxN], *P = E, *Point[MaxN];

inline void AddEdge(int x, int y)
{
++P; P -> v = y;
P -> Next = Point[x]; Point[x] = P;
}

bool Find(int x)
{
for (Edge *j = Point[x]; j; j = j -> Next)
{
if (Used[j -> v] == Index) continue;
Used[j -> v] = Index;
if (Father[j -> v] == 0 || Find(Father[j -> v]))
{
Father[j -> v] = x;
return true;
}
}
return false;
}

int main()
{
scanf("%d%d", &n, &m);
int a, b;
for (int i = 1; i <= m; ++i)
{
scanf("%d%d", &a, &b);
OK[a][b] = true;
}
for (int k = 1; k <= n; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
OK[i][j] = OK[i][j] || (OK[i][k] && OK[k][j]);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (OK[i][j]) AddEdge(i, n + j);
Index = 0;
Ans = 0;
for (int i = 1; i <= n; ++i)
{
++Index;
if (Find(i)) ++Ans;
}
Ans = n - Ans;
printf("%d\n", Ans);
return 0;
}


posted @ 2015-03-09 19:52  JoeFan  阅读(1802)  评论(0编辑  收藏  举报