HDU1150 最小顶点覆盖

 1 /*HDU1150 最小顶点覆盖
点覆盖集即一个点集,使得所有边至少有一个端点在集合里。或者说是“点” 覆盖了所有“边”。
2 题目描述:有两台机器A和B以及N个需要运行的任务。每台机器有M种不同的模式,而每个任务都恰好在一台机器上运行。 3 4 如果它在机器A上运行,则机器A需要设置为模式xi,如果它在机器B上运行,则机器A需要设置为模式yi。 5 6 每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。 7 8 建图 9 最小顶点覆盖==最大匹配 10 */ 11 #include <iostream> 12 #include <cmath> 13 #include <algorithm> 14 #include <string.h> 15 #include <stdio.h> 16 #include <set> 17 #include <stack> 18 #include <vector> 19 #define maxn 510 20 using namespace std; 21 22 vector<int> G[2*maxn]; 23 int match[2*maxn];//记录点的对应项 24 bool visit[2*maxn];//记录点是否在增广路上 25 26 int n,m,k; 27 void read(){ 28 int mx=max(n,m); 29 for(int i=1;i<=m;i++){ 30 G[i].clear(); 31 } 32 cin>>k; 33 for(int i=1;i<=k;i++){ 34 int num,x,y; 35 scanf("%d%d%d",&num,&x,&y); 36 if (x && y){ 37 G[x].push_back(y); 38 } 39 } 40 } 41 bool dfs(int s)//找到从s点出发的可增广路 42 { 43 for(int i=0;i<G[s].size();i++){ 44 int v=G[s][i]; 45 if (!visit[v]){ 46 visit[v]=true; 47 if (match[v]==0 || dfs(match[v])){//说明v对应的项有增广路 48 match[v]=s;//修改v的对应项(即互斥点)是s 49 return true; 50 } 51 } 52 } 53 return false; 54 } 55 56 int hungary(){ 57 int ans=0; 58 memset(match,0,sizeof(match));//清空匹配 59 for(int i=1;i<=n;i++){ 60 memset(visit,0,sizeof(visit));//注意清空增广路 61 if (dfs(i)) ans++; 62 } 63 return ans; 64 } 65 66 int main(){ 67 while(cin>>n && n){ 68 cin>>m; 69 read(); 70 printf("%d ",hungary()); 71 //最大匹配 72 } 73 return 0; 74 }
原文地址:https://www.cnblogs.com/little-w/p/3647928.html