二分图匹配,最小点覆盖——POJ

题目链接

题目含义

两个机器分别有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);
    }
}
原文地址:https://www.cnblogs.com/helman/p/11290903.html