pku1325(二分图最小覆盖)

http://162.105.81.212/JudgeOnline/problem?id=1325

题意:有两台机器AB,一台有n种模式,一台有m种模式,有k个任务,每个任务都可以用A的某个模式或B的某个模式完成,开始两机器均为0模式,问最少切换多少次模式可完成所有任务。

思路:两台机器的模式可理解为两个集合,每个任务可理解为连接两种模式的线,则该问题可转换为二分图问题,即拿出多少个点可以消除所有的线,就是求二分图的最小点覆盖数,由于有最小点覆盖数等于最大匹配数,因此只需要用匈牙利算法求出最大匹配数即可。

#include<iostream> using namespace std; #define maxn 1000 int N, M, uN; bool g[maxn][maxn]; int xM[maxn], yM[maxn]; bool chk[maxn]; bool find(int u) { int v; for(v=1; v<=M; v++) //B工线的数量M, if(g[u][v] && !chk[v]) { chk[v] = true; if(yM[v] == -1 || find(yM[v])) { yM[v] = u; xM[u] = v; return true; } } return false; } int MaxMatch() { int u, ret = 0; memset(xM, -1, sizeof(xM)); memset(yM, -1, sizeof(yM)); for(u= 1;u<=N; u++) //A工线的数量N; { if(xM[u] == -1) { memset(chk, false, sizeof(chk)); if(find(u)) ret++; } } return ret; } int main() { int i, id, k, x, y, res; while(scanf("%d%d%d",&N, &M, &k) && N) { memset(g, 0, sizeof(g)); for(i=0; i<k; i++) { scanf("%d%d%d",&id, &x, &y); //if(x * y != 0) //因为都是从0号开始的所有要这么构图,但是不用也能AC g[x][y] = 1; } res = MaxMatch(); printf("%d/n",res); } return 0; } 

你可能感兴趣的:(算法,任务)