题目含义
两个机器分别有n,m种模式,每个工作需要任一机器达到某个模式,问最少要变换几次模式
题目分析
将两个机器的n,m种模式作为二分图的两个集合,每个工作代表之间的一条线
题目可以化为求能覆盖所有边的最少点(取a或b的点都可以)
然后根据定理,可以转化成求最大匹配
注意,当工作需要机器的模式是0时,这个工作不用变模式就可以完成,就可以不用考虑
题目代码
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; const int maxn=3e4+7; struct edge{ int to,next; }e[1007]; int head[107],tot; void add(int u,int v){ e[tot].to=v; e[tot].next=head[u]; head[u]=tot++; } bool vis[107]; int bmach[107],n,m,k,I,x,y; void init(){ tot=0; memset(head,-1,sizeof(head)); memset(bmach,0,sizeof(bmach)); } bool find(int u){ for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(vis[v])continue; vis[v]=true; if(!bmach[v]||find(bmach[v])){ bmach[v]=u;return true; } }return false; } int main(){ while(scanf("%d",&n)){ if(n==0)return 0; scanf("%d%d",&m,&k); init(); int mx=0; for(int i=1;i<=k;i++){ scanf("%d%d%d",&I,&x,&y); if(mx<x)mx=x; if(x==0||y==0)continue; add(x,y); } int sum=0; for(int i=1;i<=mx;i++){ memset(vis,false,sizeof(vis)); if(find(i))sum++; } printf("%d ",sum); } }