题目描述:
给出一系列任务,每个任务可以在机器A的某个模式,或者在机器B的某个模式下完成。机器A和B每切换一次模式需要重启一次。问完成这些任务,最少需要重启机器多少次?
解题思路:
最小点集覆盖—— 用最少的点,覆盖所有边。
这里面,边指任务,点指机器模式。这里面的特点是在任务执行顺序没有要求的条件下才可以使用最小点集覆盖。(如果任务次序有要求应该用动规吧)。
这里具体还是使用二分图匹配的算法,找到最大匹配的边数——实际意义为找到匹配边的其中三个对应点,能够覆盖所有的任务。
代码:
#include <stdio.h>
#include <stdlib.h>
#define MAX 101
int c[MAX][MAX], n, m, k;
int visit[MAX], link[MAX];
int dfs(int v){
int i;
// printf("更新点%d\n",v);
for(i=1;i<=m;i++){
if(!visit[i] && c[v][i]){
visit[i] = 1;
if(link[i]==-1 || dfs(link[i])){
// printf("找到匹配边[%d-%d]\n",v,i);
link[i] = v;
return 1;
}
}
}
return 0;
}
main(){
int cnt, i, x, y, z;
scanf("%d",&n);
while(n!=0){
memset(c, 0, sizeof(c));
scanf("%d %d",&m, &k);
for(i=1;i<=k;i++){
scanf("%d %d %d",&x, &y, &z);
c[y][z] = 1;
}
for(i=1;i<=m;i++)
link[i] = -1;
cnt = 0;
for(i=1;i<=n;i++){
memset(visit,0,sizeof(visit));
if(dfs(i))
cnt++;
}
printf("%d\n",cnt);
scanf("%d",&n);
}
system("pause");
return 0;
}