hduoj 1150

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zimengxueying/article/details/78975772

杭电oj 1150

题目大意:有两台机器A和B以及N个需要运行的任务。每台机器有M种不同的模式,而每个任务都恰好在一台机器上运行。如果它在机器A上运行,则机器A需要设置为模式xi,如果它在机器B上运行,则机器A需要设置为模式yi。每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。
二分图的最小顶点覆盖数=最大匹配数

从百度百科上找的匈牙利算法,其中需要复习的地方还是很多啊,有关图论的相关概念,已经如何从题目中找出二分图的算法。

以下是代码:

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
#define N 110
//用到了匈牙利算法
/*
需要结合图论的有关知识
要知道增广路的含义
以及要知道如何从实际问题中抽象出算法
这一点还需要自己慢慢来
*/
int m,n;//二部图两边的顶点个数
int G[N][N];// 两顶点是否连通
int used[N];//用来检测点有没有被访问过
int result[N]; //记录下顶点增广路径的值
int dfs(int v)
{
 int i;
 for(i=0;i<m;i++){ //遍历右边的点
  if(!used[i]&&G[v][i]==1)
  {
   used[1]=1;
   if(result[i]==0||dfs(result[i]))
   {
    //这里还需要仔细的看一下,理解递归,以及增光路的含义
    result[i]=v;
    return 1;
   }
  }
 }
 return 0;
}
int solve()
{
 int ans=0;
 int i;
 ms(result,-1);
 for(i=0;i<n;i++){
  ms(used,0);
  if(dfs(i)!=0){
   ans++;
  }
 }
 return ans;
}
int main()
{
 int k;
 int j,i,l,r;
 int ans;
 while(scanf("%d",&n))
 {
  if(n==0) break;
  scanf("%d%d",&m,&k);
  ms(G,0);
  for(j=0;j<k;j++){
   scanf("%d%d%d",&i,&l,&r);
   if(l>0&&r>0){
    G[l][r]=1;
   }
  }
  ans=solve();
  printf("%d\n",ans);
 }
 return 0;
}


猜你喜欢

转载自blog.csdn.net/zimengxueying/article/details/78975772