POJ-1422 Air Raid---Bipartite graph matching & minimum path coverage

Topic link:

https://vjudge.net/problem/POJ-1422

Topic meaning:

There are n points and m directed edges. Now put some paratroopers on the points, and then the paratroopers walk along the graph until they can't go.
Each edge can only be walked by one paratrooper. Ask how many paratroopers at least

Problem solving ideas:

Minimum path coverage

Minimum path coverage = |G| - maximum number of matches

The point is, when building a graph, divide each point into two parts A1 and A2. If there is an edge A->B, add A1->B2 to the bipartite graph

The ingenuity here can be seen in the following example

For a path, the in-degree of the starting point is 0, the out-degree of the end point is 0, and the in-degree of intermediate nodes is 1.

Each point can only have at most 1 successor, and each point can only have at most 1 predecessor.

If we choose an edge (u, v), it is equivalent to matching the predecessor u with the successor v. In this way, the predecessor u and the successor v cannot match other nodes.

Using this we can compose the image like this:

Split each point into 2, which represent it as a predecessor node and a successor node respectively. Take all predecessor nodes as part A, and all successor nodes as part B.

Next, connect the edges. If there is an edge (u, v) in the original graph, connect the u of the A part and the v of the B part.

 

Do a max binary match on this:

The solid lines represent selected matches, and the dashed lines represent unselected matches.

Have you found that it has a corresponding relationship with the original image?

In this way, when the matching is over, we can directly determine the selected path through the matching situation.

But how to ensure that the minimum path coverage is obtained in this way?

If a point is the starting point of the path, there must be no match for its node in part B.

After the maximum matching algorithm, the remaining unmatched points in part B must be the least, which corresponds to the minimum required number of paths.

So the result of minimum path coverage is N-maximum number of matches.

(The above example is reproduced from: https://blog.csdn.net/tramp_1/article/details/52742572 )

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<queue>
 7 using namespace std;
 8 typedef pair<int, int> Pair ;
 9 typedef long long ll;
10 const int INF = 0x3f3f3f3f;
11 const int maxn = 300 + 10;
12 int T, n, m, cases;
13 vector<int>G[maxn];
14 int cx[maxn], cy[maxn];
15 bool vis[maxn];
16 bool dfs(int u)
17 {
18     for(int i = 0; i < G[u].size(); i++)
19     {
20         int v = G[u][i];
21         if(!vis[v])
22         {
23             vis[v]  =1;//加入增广路
24             if(cy[v] == -1 || dfs(cy[v]))
25             {
26                 cx[u] = v;
27                 cy[v] = u;
28                 return 1;
29             }
30         }
31     }
32     return 0;
33 }
34 int maxmatch()
35 {
36     int ans = 0;
37     memset(cx, -1, sizeof(cx));
38     memset(cy, -1, sizeof(cy));
39     for(int i = 1; i <= n; i++)
40     {
41         if(cx[i] == -1)
42         {
43             memset(vis, 0, sizeof(vis));
44             ans += dfs(i);
45         }
46     }
47     return ans;
48 }
49 int main()
50 {
51     cin >> T;
52     while(T--)
53     {
54         scanf("%d%d", &n, &m);
55         int x, y;
56         for(int i = 0; i <= n; i++)G[i].clear();
57         for(int i = 1; i <= m; i++)
58         {
59             scanf("%d%d", &x, &y);
60             G[x].push_back(y);
61         }
62         cout<<(n - maxmatch())<<endl;
63     }
64     return 0;
65 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324395240&siteId=291194637
Recommended