POJ 1325 简单基础匈牙利二分匹配:最小点覆盖

来源:互联网 发布:ubuntu系统软件包缺失 编辑:程序博客网 时间:2024/05/08 04:10

POJ 1325:http://poj.org/problem?id=1325

题意:两台机器可以工作。各有n个和m个工作模式。皆标记为0、1、2、3、...... 、n(m)

           给出k个任务,每个任务在两台机器上都可以完成,其分别在两台机器上完成需要对应的工作模式为(i,j)

                                                           表示在第一台机器上工作需要模式i,第二台机器上工作需要模式 j 。

         

机器初始为0工作状态。每一次改变工作状态需要重启。

求,完成所有工作最少重启几次。

画个图,左为左边机器的各个工作模式,右边为右边机器的各个工作模式。一个任务对应一条边。

很容易看出为——最小点覆盖。 选择最少的点覆盖所有边——选择最少的重启次数完成所有任务。

最少点覆盖数 = 最大匹配数。


WA了的主要原因是:

                         题目注明,起初两台机器的工作状态皆为0 。 所以含有0点的边都去掉,不需要考虑!!!!

                         然后模板。


#include"cstdio"#include"cstring"#include"vector"#include"string"#include"iostream"#include"cstdlib"using namespace std;#define inf 109#define loop(x,y,z) for(x=y;x<z;x++)int n,m;vector<int>edge[109];int ans[inf],book[inf];int sum;void init(){    int i;    sum=0;    loop(i,1,n)    edge[i].clear();    memset(ans,-1,sizeof ans);}int dfs(int v){    int i,len;    len=edge[v].size();    loop(i,0,len)    {        int u=edge[v][i];        if(!book[u])        {            book[u]=1;            if(ans[u]==-1||dfs(ans[u]))            {                ans[u]=v;                return 1;            }        }    }    return 0;}void XYL(){    int i;    loop(i,1,n)    {        memset(book,0,sizeof book);        sum+=dfs(i);    }}int main(){    int i,j,k,p;    while(~scanf("%d",&n)&&n)    {        scanf("%d%d",&m,&p);        init();        while(p--)        {            scanf("%d%d%d",&k,&i,&j);            if(i==0||j==0)continue;            edge[i].push_back(j);        }        XYL();        printf("%d\n",sum);    }    return 0;}


0 0
原创粉丝点击