直接套模板 + 建图方式。。。。至少会套模板了。。。。把最小生成树的弄完再 。。。 回来证明。。。。
//
Poj 1325 Machine Schedule(求二分图的最小覆盖数)
题意:有A,B两台机器,和K个需要运行的任务;A,B分别有N,M中模式;
每个任务都既可以在A中以x模式,也可以在B中以y模式完成;
每台机器可以按照任意顺序执行,但是每台机器每转化一次模式就需重启一次;
安排一种顺序,使机器重启次数最少;(开始时A,B都处于模式0);
算法:二分图的建立,匈牙利算法,
主要是建模;本题建模需要一点技巧;
如图,因为我们需要最少的模式数,将所有的任务覆盖;应该把每个任务看成一
条边,把A机器的每个模式看成一个X结点,B机器的每个模式看成一个Y结点;
这样就建立了二分图;我们要求的是用最少的点将所有的边覆盖;
有以下结论,这个覆盖数等于最大匹配数M;
下面是LRJ的证明,很好很强大;
①M个是足够的,只需要让他们覆盖最大的匹配的M条边,则其他边一定被覆盖
(如果有边e不被覆盖,把e加入后得到一个更大的匹配)
②M个是必需的,仅考虑形成最大匹配的M条边,由于两两无公共点,因此至少
需要M个点才能把它们覆盖;
最后,对于输入中可以在模式0下完成的直接不用存储;
//
1 //Accepted 1364 C++ 0 260 2 #include <stdio.h> 3 #include <string.h> 4 const int N = 151; 5 int mapp[N][N], chk[N], match[N]; 6 int m, n, k, res; 7 int dfs(int p) 8 { 9 int i, t; 10 for (int i = 1; i <= m; i++) 11 if (mapp[i][p] && !chk[i]) { 12 chk[i] = 1; 13 t = match[i]; 14 match[i] = p; 15 if (t == -1 || dfs(t)) 16 return 1; 17 match[i] = t; 18 } 19 return 0; 20 } 21 22 void pro() 23 { 24 for (int i = 1; i <= n; i++) { 25 memset(chk, 0, sizeof(chk)); 26 res += dfs(i); 27 } 28 } 29 30 int main() 31 { 32 while (scanf("%d", &n) && n) 33 { 34 res = 0; 35 memset(mapp, 0, sizeof(mapp)); 36 memset(match, -1, sizeof(match)); 37 scanf("%d%d", &m, &k); 38 for (int i = 0; i < k; i++) 39 { 40 int u, v, num; 41 scanf("%d%d%d", &num, &u, &v); 42 if (!u||!v) continue; 43 mapp[u][v] = 1; 44 } 45 pro(); 46 printf("%d\n", res); 47 } 48 return 0; 49 }
原文地址:http://www.cnblogs.com/gyf123/p/3768463.html