您的位置:首页 > 其它

hdu 1150二分图最小顶点覆盖

2012-04-10 22:46 549 查看
题目大意:

有两台机器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;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: