标签:minimal ase div str ems contains roman use hang
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 13071 | Accepted: 5575 |
Description
Input
Output
Sample Input
5 5 10 0 1 1 1 1 2 2 1 3 3 1 4 4 2 1 5 2 2 6 2 3 7 2 4 8 3 3 9 4 3 0
Sample Output
3题意:
有A,B两台机器。机器A有 n种工作模式,分别为 mode_0,mode_1,mode_2.....,机器B有 m种工作模式,分别为 mode_0,mode_1。mode_2.....。刚開始A。B的工作模式都是mode_0。
给定K个任务。表示为(i 。x。y),意思是作业 i 能够工作在机器A的mode_x模式或者机器B的mode_y的模式。
为了完毕全部的工作,必须时不时的切换机器的工作模式,但机器工作模式的切换仅仅能通过重新启动机器完毕,问你最少重新启动多少次机器。才干把工作分配完。
解析:
一看有A ,B种机器,再依据题意,两种机器有匹配关系,我们首先构造二分图,把A的n个mode和B的m个mode看做图的顶点。假设某个任务能够在A的mode_i 或B的mode_j 上完毕。则从Ai 到 Bj连一条边,这样就构成了二分图。
由题意可知,本意要求的是二分图的最小点覆盖集问题,即最小的顶点集合,“覆盖”全部的边,能够转化成二分图的最大匹配问题。
二分图的最小点覆盖数 == 最大匹配数。
另外要注意,机器A 和机器B最初都是在mode_0。所以对那些能够在机器A的mode_0或者机器B的模式_0工作的作业,在完毕这些作业时是不须要重新启动机器的。
一開始没考虑这里。贡献了一次wa。
#include <cstdio> #include <cstring> #include <algorithm> #define maxn 110 using namespace std; int map[maxn][maxn]; int used[110]; int link[maxn]; int n, m, k; void getmap(){ while(k--){ int c, a, b; scanf("%d%d%d", &c, &a, &b); if(a == 0 || b == 0) continue; map[a][b] = 1; } } bool dfs(int x){ for(int i = 0; i < m; ++i){ if(!used[i] && map[x][i]){ used[i] = 1; if(link[i] == -1 || dfs(link[i])){ link[i] = x; return true; } } } return false; } int hungary(){ int ans = 0; memset(link, -1, sizeof(link)); for(int i = 0; i < n; ++i){ memset(used, 0, sizeof(used)); if(dfs(i)) ans++; } return ans; } int main (){ while(scanf("%d", &n), n){ scanf("%d%d", &m, &k); memset(map, 0, sizeof(map)); getmap(); int sum = 0; sum = hungary(); printf("%d\n", sum); } return 0; }
POJ 1325 && ZOJ 1364--Machine Schedule【二分图 && 最小点覆盖数】
标签:minimal ase div str ems contains roman use hang
原文地址:http://www.cnblogs.com/gavanwanggw/p/7029192.html