2014-11-04 23:43:11
思路:比较好建图的题,X集合是A机器,Y集合是B机器,每条关系建一条有向边,然后就是最小点覆盖问题了。
主要注意的是:A、B机器刚开始的状态为0,所以只要job可以用A的mod0或B的mod0,就不用建边。
1 /************************************************************************* 2 > File Name: 1325.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Tue 04 Nov 2014 11:12:18 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 110; 27 const int maxm = 1010; 28 29 int n,m,k; 30 int first[maxn],next[maxm],ver[maxm],ecnt; 31 int mat[maxn],used[maxn]; 32 33 void Init(){ 34 memset(first,-1,sizeof(first)); 35 ecnt = 0; 36 } 37 38 void Add_edge(int u,int v){ 39 next[++ecnt] = first[u]; 40 ver[ecnt] = v; 41 first[u] = ecnt; 42 } 43 44 bool find(int p){ 45 for(int i = first[p]; i != -1; i = next[i]){ 46 int v = ver[i]; 47 if(used[v] == 0){ 48 used[v] = 1; 49 if(mat[v] == 0 || find(mat[v])){ 50 mat[v] = p; 51 return true; 52 } 53 } 54 } 55 return false; 56 } 57 58 int Hungary(){ 59 int ans = 0; 60 memset(mat,0,sizeof(mat)); 61 for(int i = 0; i < n; ++i){ 62 memset(used,0,sizeof(used)); 63 if(find(i)) ++ans; 64 } 65 return ans; 66 } 67 68 int main(){ 69 int a,b,c; 70 while(scanf("%d",&n) != EOF && n){ 71 scanf("%d%d",&m,&k); 72 Init(); 73 for(int i = 1; i <= k; ++i){ 74 scanf("%d%d%d",&a,&b,&c); 75 if(b == 0 || c == 0) 76 continue; 77 Add_edge(b,c); 78 } 79 printf("%d\n",Hungary()); 80 } 81 return 0; 82 }