题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1150
题目大意:
给你两台机器A和B,A机器有n种模式,B机器有m种模式,初始时都是0,现在给你k个任务,每个任务可以由机器A的x模式完成或者机器B的y模式完成,而每次改变机器的模式都要重启一次,问你最少的重启次数使得完成所有任务!
解题思路:
首先初始化为0,所以有模式0完成的任务可以不考虑,然后我们可以考虑建立二分图,机器A和机器B的模式互相连接,某个任务由A的x和B的y完成那么x与y相连,所以我们转换下题目的模型就是在这个二分图中找出最少的点使得所有的边都至少有一个端点被选中,而这就是最小点覆盖的模型,而最小点覆盖=最大匹配
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1000 + 10; 5 const int INF = 1e9; 6 bool Map[maxn][maxn]; 7 int cx[maxn], cy[maxn]; 8 int cntx, cnty; 9 bool vis[maxn]; 10 bool dfs(int u) 11 { 12 for(int v = 1; v <= cnty; v++) 13 { 14 if(Map[u][v] && !vis[v]) 15 { 16 vis[v] = 1; 17 if(cy[v] == -1 || dfs(cy[v])) 18 { 19 cx[u] = v; 20 cy[v] = u; 21 return 1; 22 } 23 } 24 } 25 return 0; 26 } 27 int maxmatch() 28 { 29 int ans = 0; 30 memset(cx, -1, sizeof(cx)); 31 memset(cy, -1, sizeof(cy)); 32 for(int i = 1; i <= cntx; i++) 33 { 34 if(cx[i] == -1) 35 { 36 memset(vis, 0, sizeof(vis)); 37 ans += dfs(i); 38 } 39 } 40 return ans; 41 } 42 int main() 43 { 44 int n, i, u, v; 45 while(cin >> cntx && cntx) 46 { 47 cin >> cnty >> n; 48 memset(Map, 0, sizeof(Map)); 49 while(n--) 50 { 51 cin >> i >> u >> v; 52 Map[u][v] = 1; 53 } 54 cout<<maxmatch()<<endl; 55 } 56 return 0; 57 }