现在的位置: 首页 > 综合 > 正文

hdoj 1150 Machine Schedule

2018年04月02日 ⁄ 综合 ⁄ 共 1035字 ⁄ 字号 评论关闭

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1150

/*大致题意:
有两台机器A和B以及k个需要运行的任务。每台机器有n,m种不同的模式,而每个任务都恰好能在一台机器上运行。
机器A上有模式 mode_0, mode_1, …, mode_n-1,机器B上有模式: mode_0, mode_1, … , mode_m-1。
开始的工作模式都是mode_0。每个任务有对应的运行模式,(i, x, y)表示i任务对应的A B机器上的运行模式mode_x, mode_y。
每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。
请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。并求其值。
*/
/*
每个任务要有对应A B机器的模式中至少要有一种来运行,问题转化为,求二分图中最少的点(模式)使得每个边(模式对应的任务)至少和其中的一个点覆盖。
也就是二分图最小顶点覆盖问题
*/
#include<iostream>   
using namespace std;  
const int MAX = 102;  
bool linkMap[MAX][MAX];  
int  crossPath[MAX];  
bool used[MAX];  
int n, m;  
bool search(int u)  
{  
	for (int i=1;i<m;i++) {  
		if (linkMap[u][i]&&!used[i]) {  
			used[i]=1;//保证路径上无重复点出现   
			if (crossPath[i]==-1||search(crossPath[i])) {  
				crossPath[i]=u;//增广路径的取反
				return true;  
			}  
		}  
	}  
	return false;  
}    
int main()  
{   
	int k;  
	while(cin>>n,n) {  
		cin>>m>>k;  
		memset(linkMap, false, sizeof(linkMap));//构建二分图
		for(int i =0; i < k; i++) {   
			int v1, v2; 
			cin>>v1>>v1>>v2;
			if(v1&&v2)
				linkMap[v1][v2] = true;//连接左右两边
		}
		int count = 0;
		memset(crossPath, -1, sizeof(crossPath));  
		for(int i= 1; i<n; i++) { 
			memset(used, 0, sizeof(used));  
			if(search(i)) //查找增广路径
				count ++;
		}
		cout<< count <<endl;
	}  
	return 0;  
}

抱歉!评论已关闭.