二分图——最大不可互相到达数 = 最小路径覆盖数

study from:

https://blog.csdn.net/winter2121/article/details/79849472

https://nanti.jisuanke.com/t/19979

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <time.h>
 6 #include <string>
 7 #include <set>
 8 #include <map>
 9 #include <list>
10 #include <stack>
11 #include <queue>
12 #include <vector>
13 #include <bitset>
14 #include <ext/rope>
15 #include <algorithm>
16 #include <iostream>
17 using namespace std;
18 #define ll long long
19 #define minv 1e-6
20 #define inf 1e9
21 #define pi 3.1415926536
22 #define nl 2.7182818284
23 const ll mod=1e9+7;//998244353
24 const int maxn=1e2+10;
25 
26 bool vis[maxn];
27 int cony[maxn],r[maxn][maxn],n;
28 
29 bool dfs(int x)
30 {
31     int y;
32     for (y=1;y<=n;y++)
33         if (!vis[y] && r[x][y])
34         {
35             vis[y]=1;
36             if (cony[y]==0 || dfs(cony[y]))
37             {
38                 cony[y]=x;
39                 return 1;
40             }
41         }
42     return 0;
43 }
44 
45 int main()
46 {
47     int sum,t,m,i,j,k,x,y;
48     scanf("%d",&t);
49     while (t--)
50     {
51         scanf("%d%d",&n,&m);
52         memset(r,0,sizeof(r));
53         for (i=1;i<=m;i++)
54         {
55             scanf("%d%d",&x,&y);
56             r[x][y]=1;
57         }
58 
59         for (k=1;k<=n;k++)
60             for (i=1;i<=n;i++)
61                 for (j=1;j<=n;j++)
62                     r[i][j]|=r[i][k]&r[k][j];
63 
64         sum=n;
65         memset(cony,0,sizeof(cony));
66         for (i=1;i<=n;i++)
67         {
68             memset(vis,0,sizeof(vis));
69             sum-=dfs(i);
70         }
71         printf("%d\n",sum);
72     }
73     return 0;
74 }

另外:(copy from other)

最大匹配数:最大匹配的匹配边的数目

最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择

最大独立数(最大团):选取最多的点,使任意所选两点均不相连

最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径长可以为 0(即单个点)。

定理1:最大匹配数 = 最小点覆盖数(这是 Konig 定理)

定理2:最大匹配数 = 最大独立数

定理3:最小路径覆盖数 = 顶点数 - 最大匹配数

猜你喜欢

转载自www.cnblogs.com/cmyg/p/9556284.html
今日推荐