hdu - 1150 Machine Schedule (二分图匹配最小点覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=1150
有两种机器,A机器有n种模式,B机器有m种模式,现在有k个任务需要执行,没切换一个任务机器就需要重启一次,
如果任务i在机器A上执行,A机器需要一个对应的模式A,如果在机器B上执行,机器A需要一个模式B.
一直就是机器A在切换模式,现在让你安排一种合理的任务执行顺序,让机器重启次数最少.
每个任务之间连一条边.二分图的最小顶点覆盖就是求最少的点可以连接所有的边,然后转化成最大匹配即可.
这题就是初始状态是0,所以如果有一个任务的顶点为0,就不需要加入,因为不需要代价。
1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 using namespace std; 5 const int maxn = 105; 6 int n,m,k; 7 vector<int>G[maxn]; 8 int link[maxn]; 9 bool vis[maxn]; 10 11 void add_edge(int u,int v) 12 { 13 G[u].push_back(v); 14 //G[v].push_back(u); 15 } 16 17 bool dfs(int u) 18 { 19 for(int i=0;i<G[u].size();i++) 20 { 21 int v=G[u][i]; 22 if(!vis[v]) 23 { 24 vis[v]=true; 25 if(link[v]==-1||dfs(link[v])) 26 { 27 link[v]=u; 28 return true; 29 } 30 } 31 } 32 return false; 33 } 34 int main() 35 { 36 //freopen("a.txt","r",stdin); 37 int a,b,c; 38 while(~scanf("%d",&n)&&n) 39 { 40 scanf("%d%d",&m,&k); 41 for(int i=0;i<maxn;i++) G[i].clear(); 42 for(int i=0;i<k;i++) 43 { 44 scanf("%d%d%d",&a,&b,&c); 45 if(b>0&&c>0) 46 add_edge(b,c); 47 } 48 int ans=0; 49 memset(link,-1,sizeof(link)); 50 for(int i=0;i<n;i++) 51 { 52 memset(vis,0,sizeof(vis)); 53 if(dfs(i)) ans++; 54 } 55 printf("%d\n",ans); 56 } 57 return 0; 58 }