Title Link: BZOJ-1143
Problem analysis
This problem on the Bzoj only requires the output of the most optional number of sacrificial sites, is a long anti-chain length of the bare topic.
Here are some of the relevant knowledge:
in a direction-free graph, there are some definitions and properties as follows:
Chain: A chain is a collection of points, any two points on the chain X, y, satisfies either x can reach Y, or y can reach X.
Anti-chain: A reverse chain is a collection of points, any two points on the chain X, y, satisfies x cannot reach Y, and y also cannot reach X.
So obviously the problem is to find the longest anti-chain length.
A theorem: longest inverse chain length = minimum chain coverage (covering all vertices with minimal chain)
Duality theorem: Longest chain length = minimum reverse chain coverage
So what we're asking for is this minimal chain coverage of the non-circular graph. The minimum chain overlay is the minimum path coverage that the path can intersect.
Let's start by looking at how the path cannot be intersected by the minimum path overlay:
Create a two-part graph, both sides are N points, the original image of each point I corresponds to two, on the left is called I1, on the right is called i2.
Then, if there is an edge (x, y) in the original image, The edge of (x1, y2) is established in the dichotomy.
After this establishment of the binary map, the original number of the number of the N-two graph maximum match = The original image of the minimum path coverage (path can not intersect).
Why is that right? We can think that at the beginning each point of the original image is a separate path, and then each time we select an edge in the binary graph, which is to connect two paths into one path, the number of answers is reduced by 1.
And the path is not intersect, so we in the binary graph selected edge is also can not intersect, so is the largest match of the binary graph.
After knowing the minimum path that the path cannot intersect, how can the path overlay (that is, the smallest chain overlay) intersect the paths?
We will make the original Floyd delivery closure, then we can know any two X, y,x can reach Y.
If two points x, y, satisfies x to reach Y, then the edge is established in the binary graph (x1, y2).
This is actually equivalent to the original image is modified, as long as x can reach Y, directly connected to an edge (x, y), so that you can "bypass" the original image of some of the points occupied by other paths, directly constructs a new path.
This overrides the minimum path that can intersect to the minimum path that the path cannot intersect.
Code
#include <iostream> #include <cstring> #include <cstdlib> #include <cstring> #include < Cstdio> #include <algorithm>using namespace Std;const int maxn = + 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;}
[Bzoj 1143] [CTSC2008] Sacrificial river "longest anti-chain"