poj1325 Machine Schedule【最小顶点覆盖】

来源:互联网 发布:嘉贝逸飞淘宝网站 编辑:程序博客网 时间:2024/06/08 05:43

题目链接:http://poj.org/problem?id=1325
题意:有k个工作,有两种机器A,B,A机器有n种工作模式,B有m种工作模式,A,B的工作模式初始都为0,对于工作i,只能工作在A的x模式或B的y模式,而每次为机器更换工作模式需要重启机器,问你完成所有工作的情况下,最少的重启机器次数
解析:这是一道最小顶点覆盖的题目,由题意可得,这是二分图,故最小顶点覆盖等于最大匹配数,对于AB两个顶点集建图,(i,x,y)就建一条边,建完图,做二分图匹配即可

#include <iostream>#include <algorithm>#include <string>#include <cstring>#include <cstdio>using namespace std;const int maxn = 405;struct node{    int to,next;}edge[5*maxn];int head[maxn],cnt;int match[maxn],vis[maxn];void init(){    memset(head,-1,sizeof(head));    memset(match,-1,sizeof(match));    cnt = 0;}void addEdge(int u,int v){    edge[cnt].to = v;    edge[cnt].next = head[u];    head[u] = cnt++;}bool dfs(int u){    for(int i=head[u];i!=-1;i = edge[i].next)    {        int v = edge[i].to;        if(!vis[v])        {            vis[v] = 1;            if(match[v]==-1||dfs(match[v]))            {                match[v] = u;                match[u] = v;                return true;            }        }    }    return false;}int main(void){    int n,m,k;    while(~scanf("%d",&n)&&n)    {        scanf("%d %d",&m,&k);        init();        for(int i=1;i<=k;i++)        {            int j,x,y;            scanf("%d %d %d",&j,&x,&y);            if(x==0||y==0)                continue;            addEdge(x,y+n);        }        int ans = 0;        for(int i=0;i<n;i++)        {            memset(vis,0,sizeof(vis));            if(dfs(i))                ans++;        }        printf("%d\n",ans);    }    return 0;}