hdu 1150二分图最小顶点覆盖

题目大意:

有两台机器A和B以及N个需要运行的任务。每台机器有M种不同的模式,而每个任务都恰好在一台机器上运行。

如果它在机器A上运行,则机器A需要设置为模式xi,如果它在机器B上运行,则机器A需要设置为模式yi。

每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。


在二分图中求最少的点,让每条边都至少和其中的一个点关联,这就是:二分图的顶点求最少的点,让每条边都至少和其中的一个点关联,这就是

二分图的最小顶点覆盖数=最大匹配数

本题就是求最小顶点覆盖数的。



#include 
#include 
#include 


#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))


#define FALSE	0
#define TRUE	1


#define infinity    0x0f0f0f0f
#define minus_inf    0x80808080


#define MAXSIZE	109


typedef struct tagNODE {
	int mode[100] ;
} ;


int n, m, k, cnt ;
int job, m1, m2 ;


int cover[MAXSIZE], link[MAXSIZE] ;
int adj[MAXSIZE][MAXSIZE] ;


int find (int i)
{
	int j ;
	for (j = 1 ; j < m ; ++j)
	{
		// j 在本次查找中没有被覆盖过, 且i 能与j 连通
		if (cover[j] == FALSE && adj[i][j] == TRUE)
		{
			cover[j] = TRUE ;	
			if (link[j] == FALSE || find (link[j]) == TRUE)
			{
				link[j] = i ;
				return 1 ;
			}
		}
	}
	return 0 ;
}


int main ()
{
	int i, j ;
	while (scanf ("%d", &n), n)
	{
		memset (adj, FALSE, sizeof (adj)) ;
		
		scanf ("%d%d", &m, &k) ;
		for (i = 0 ; i < k ; ++i)
		{
			scanf ("%d%d%d", &job, &m1, &m2) ;
			adj[m1][m2] = 1 ;
		}
		
		cnt = 0 ;
		memset (link, FALSE, sizeof (link)) ;
		// i 不用从0 开始,因为0 是初始状态,即是说,
		// 所有用0 状态解决的工作都不算入"重启次数"中,
		// 因为这些工作根本不需要重启机器
		for (i = 1 ; i < n ; ++i)
		{
			memset (cover, FALSE, sizeof (cover)) ;
			if (find(i) == TRUE)
				++cnt ;
		}
		printf ("%d\n", cnt) ;
	}
	return 0 ;
}

c++版本

#include 
#include 
#include 
using namespace std;
bool mark1[100],mark2[100];
int list[100];
int n,m,edge,num;
vector > v;
bool dfs(int to)
{
	int i ,point ,s = list[to];
	for(i=0;i>n)
	{
		if(n==0)
			break;
		v.clear();
		v.resize(n);
		cin>>m>>edge;
		for(i=0;i>j>>s>>d;
			v[s].push_back(d);
		}
		solve();
	}
	return 0;
}

你可能感兴趣的:(二分图)