标签:call enc nim tput name memset sizeof ati 机器
InputThe input file for this program consists of several configurations. The first line of one configuration contains three positive integers: n, m (n, m < 100) and k (k < 1000). The following k lines give the constrains of the k jobs, each line is a triple: i, x, y.
The input will be terminated by a line containing a single zero.
OutputThe output should be one integer per line, which means the minimal times of restarting machine.
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以及N个需要运行的任务。每台机器有M种不同的模式,而每个任务都恰好在一台机器上运行。如果它在机器A上运行,则机器A需要设置为模式xi,如果它在机器B上运行,则机器A需要设置为模式yi。每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少(kuangbin大佬的权威解释,比较通俗易懂,就借用一下了,望大佬莫怪罪啊)。
思路:每个任务的两个模式之间建一条边,很显然构成了一张二分图,现在我们需要使重启次数最小,相当于求该图的最小点覆盖。
根据二分图的特性--最小点覆盖=最大匹配数,可以轻松做出此题。不过因为初始状态为零,所以如果有模式为0的边就不添加了)
代码如下:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int match[110][110],vis[110],n,m; int ye[110]; bool find(int x) { for(int i=1;i<=m;i++) { if(match[x][i]==1&&!vis[i]) //如果存在x到i的边且该边没有被匹配 { vis[i]=1; //匹配这条边,将该边设为已被访问 if(ye[i]==-1) //如果该边没有匹配边,设置x为该边的匹配边 { ye[i]=x; return true; } else { if(find(ye[i])==true)//如果该边被匹配了,寻找边ye[i]是否能与其他边匹配,如果能,空出i的位置 { ye[i]=x; return true; } } } } return false; } int main() { int k,i,x,y; int ans; while(~scanf("%d",&n)) { ans=0; memset(match,0,sizeof(match)); memset(ye,-1,sizeof(ye)); if(n==0) { break; } scanf("%d%d",&m,&k); while(k--) { scanf("%d%d%d",&i,&x,&y); match[x][y]=1; } for(int j=1;j<=n;j++) { memset(vis,0,sizeof(vis)); if(find(j)==true) { ans++; } } printf("%d\n",ans); } return 0; }
每天刷题,身体棒棒!
HDU1150 Machine Schedule(二分图最大匹配、最小点覆盖)
标签:call enc nim tput name memset sizeof ati 机器
原文地址:http://www.cnblogs.com/stxy-ferryman/p/7476171.html