hdu 1150二分图最小顶点覆盖

题目大意:

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

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

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


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

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

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



#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#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 <string>
#include <vector>
#include <iostream>
using namespace std;
bool mark1[100],mark2[100];
int list[100];
int n,m,edge,num;
vector<vector<int> > v;
bool dfs(int to)
{
	int i ,point ,s = list[to];
	for(i=0;i<v[s].size();i++)
	{
		point=v[s][i];
		if(!mark2[point])
			continue;
		mark2[point] = false;
		if(list[point] == -1 || dfs(point))
		{
			list[point] = s;
			return true;
		}
	}
	return false;
}

void solve()
{
	int i,j,point;
	bool flag=false;
	memset(mark1,true,sizeof(mark1));
	memset(list,-1,sizeof(list));
	num=0;
	for(i=0;i<n;i++)
	{
		for(j = 0; j < v[i].size();j++)
		{
			if(list[v[i][j]] == -1)
			{
				mark1[i] = false;
				list[v[i][j]] = i;
				num++;
				if(i==0)
					flag=true;
				break;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		if(mark1[i])
		{
			if(!v[i].empty())
			{
				memset(mark2,true,sizeof(mark2));
				for(j=0;j<v[i].size();j++)
				{
					point = v[i][j];
					if(!mark2[point]) continue;
					mark2[point] = false;
					if(list[point] == -1 || dfs(point))
					{
						list[point] = i;
						num++;
						break;
					}
				}
			}
			mark1[i] =false;
		}
	}
	if(flag || list[0]!=-1)
		cout<<num-1<<endl;
	else
		cout<<num<<endl;
}

int main()
{
	int i,j,s,d;
	while(cin>>n)
	{
		if(n==0)
			break;
		v.clear();
		v.resize(n);
		cin>>m>>edge;
		for(i=0;i<edge;i++)
		{
			cin>>j>>s>>d;
			v[s].push_back(d);
		}
		solve();
	}
	return 0;
}

   

你可能感兴趣的:(c,工作,list,struct,ini,任务)