poj 1325 && zoj 1364 Machine Schedule

来源:互联网 发布:php文件上传源代码 编辑:程序博客网 时间:2024/05/16 08:52

题意:有两台机器A,B。机器A有n中工作模式,机器B有m种工作模式。给定k个作业,每个作业可以在机器A的模式x或者机器B的模式y下工作。


分析:某个任务可以在A的模式x或B的模式y下完成,则可以连接一条 x->y的边,构造一个二分图,然后我们要求的是用最少的点去覆盖所有的边,即最小点覆盖集。然后二分图中的最小点覆盖集等于最大匹配,虽然我并不知道这是为什么~。

先记住这个结论:二分图的点覆盖数 == 匹配数。


以下附上代码:

#include <algorithm>#include <iostream>#include <sstream>#include <fstream>#include <cstring>#include <cstdio>#include <vector>#include <cctype>#include <cmath>#include <stack>#include <queue>#include <list>#include <map>#include <set>using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 105;int n,m,k;int g[maxn][maxn];int cx[maxn],cy[maxn];bool vis[maxn];bool input(){  int i,j;  int u,v;  scanf("%d",&n);  if(n == 0) return false;  scanf("%d%d",&m,&k);    for(i = 0; i <= n; i++){    for(j = 0; j <= m; j++){      g[i][j] = 0;    }  }    for(j = 0; j < k; j++){    scanf("%d%d%d",&i,&u,&v);    g[u][v] = 1;  }  return true;}int path(int u){  for(int v = 1; v <= m; v++){    if(!vis[v] && g[u][v]){//之前没访问v       vis[v] = 1;      if(cy[v] == -1 || path(cy[v])){        cx[u] = v;        cy[v] = u;        return 1;      }    }  }  return 0;}int maxMatch(){  int res = 0;  fill(cx,cx+n+1,-1);  fill(cy,cy+m+1,-1);  for(int i = 1; i <= n; i++){    if(cx[i] == -1){//未匹配       fill(vis,vis+m+1,0);      res += path(i);    }  }  return res;}void solve(){  printf("%d\n",maxMatch());}int main(){  while(input()){    solve();  }return 0;}


0 0
原创粉丝点击