POJ 1325 Machine Schedule 二分图 最小点覆盖

原创 2013年12月03日 15:12:21

题目大意:有两台机器,分别有m,n个状态,最开始的时候都位于状态0,现在给定了k个任务,每个任务都可以在A的某一个状态或B的某一个状态运行,求问完成所有的任务所需的切换机器状态的总次数


机器的每一个状态用一个点表示,显然这是一个二分图,如果在每个任务指定的两个状态连一条线的话就可以用一条边代表这个任务,而让这个任务在某台机器上执行就是给这条边选择一个端点,每切换一次状态就是选择一个点,那么这道题就转化为了:求最少的顶点,使边集中的每一条边都与某个顶点关联,即求二分图的最小点覆盖

再由Konig定理,二分图的最小点覆盖数=最大匹配数,那么用匈牙利算法就可以解决了~

(顺便查了一下才知道原来Konig就是柯尼希啊~不知道这个定理和物理学的质点动能那个定理有啥关系没......)


关于匈牙利算法:

算法思想很简单,不断的找增广路,然后把路上的边取反(实际操作上改一下匹配的对应关系就可以了),直到找不到为止,实现起来也很容易

另外对于这道题,因为最开始两台机器的状态都是0,所以与0相连的边是不需要转换状态的,这些边当成不存在就好了


下面是具体的代码

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctype.h>
#define MAXN 300

int a[MAXN][MAXN]; // 邻接矩阵
int match[MAXN]; // 标记Y集中的顶点匹配的对象,未匹配为-1
int vis[MAXN]; // 在某一次访问的过程中Y集中的该点是否被访问
int nx, ny; // xy集元素的个数
int total; // 最大匹配数目

// 从X集中的v点出发,寻找一条增广路
// 如果能找到返回true
bool find(int v)
{
    // 枚举每一个y集中的点
    for (int i = 0; i < ny; ++i)
    {
        // 若这两点间存在边而且i点尚未访问
        if (a[v][i] && !vis[i])
        {
            vis[i] = 1;
            // 递归终点为match[i] = -1,即增广路的另一个端点
            // 若该点有匹配,查看是否存在从对应匹配点出发的增广路
            if (match[i] == -1 || find(match[i]))
            {
                match[i] = v; // 修改匹配对象
                return true;
            }
        }
    }
    return false;
}

// 读入整数
inline void scan(int &x)
{
    char c;
    while ((c = getchar()) && !isdigit(c));
    x = c - '0';
    while ((c = getchar()) && isdigit(c))
    {
        x = x * 10 + c - '0';
    }
}

// 图初始化
void init()
{
    int k;
    total = 0;
    memset(match, -1, sizeof(match));
    memset(a, 0, sizeof(a));
    scan(k);
    for (int i = 0; i < k; ++i)
    {
        int t, b, c;
        scan(t); scan(b); scan(c);
        if (b == 0 || c == 0)
            continue;
        a[b][c] = 1;
    }
}

int main()
{
    int t;

    while (1)
    {
        scan(nx);
        if (nx == 0)
            break;
        scan(ny);
        init();
        for (int i = 0; i < nx; ++i)
        {
            // 枚举每一个起点,重置访问标记
            // 若找到增广路则长度+1
            memset(vis, 0, sizeof(vis));
            if (find(i))
            {
                ++total;
            }
        }
        /*for (int i = 0; i < ny; ++i)
        {
            printf("%d: %d\n", i, match[i]);
        }*/
        printf("%d\n", total);
    }
    return 0;
}


poj 1325 Machine Schedule(二分图的最小点覆盖)

Machine Schedule Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: ...

POJ-1325-Machine Schedule-最小点覆盖(二分图-匈牙利算法)

题意: 有两台机器,有多个任务,每个任务都可在这两台机器上运行,不过不同的模式需要重启电脑,很浪费时间,现在要找出最好的调度方式,减少重启次数。 把机器A看作一个点集,机器B一个点集,...
  • viphong
  • viphong
  • 2016年03月11日 11:36
  • 642

poj 1325 Machine Schedule 二分图最小点覆盖=最大匹配

Description As we all know, machine scheduling is a very classical problem in computer science and ...

POJ 1325 Machine Schedule 二分图最小点覆盖

题意: 有A,B两个机器,分别有n,m个档位,有k件工作,可以由x档位的A机器或者y档位的B机器完成。 问,可以改变完成工作的顺序,使切换档位的次数最小。 每件工作对应2个完成的档位,可以构建二...

poj1325 Machine Schedule (最小点覆盖 二分图匹配)

题意: 有一些两个机器A和B,分别有n种模式和m种模式, 现在有k个任务,每个任务可以在A机器的x模式下完成,也可以在B机器的y模式下完成。 A和B一开始都是模式0,每变换一次模式要重启一次,问...

POJ 1325 && ZOJ 1364--Machine Schedule【二分图 && 最小点覆盖数】

由题意可知,本意要求的是二分图的最小点覆盖集问题,即最小的顶点集合,“覆盖”所有的边,可以转化成二分图的最大匹配问题。 二分图的最小点覆盖数 == 最大匹配数。...
  • hpuhjh
  • hpuhjh
  • 2015年08月24日 10:02
  • 611

HDU1150/POJ1325_Machine Schedule(二分图/最小点覆盖=最大匹配)

解题报告 题目传送门 题意: A机器有n个模式,B机器有m个模式,每个作业可以在任何机器的特定模式下工作,转换模式需要耗时,求最小耗时 思路: 把AB两机器的模式当成二分图顶点,模式之间的连线就是某个...

POJ 1325 Machine Schedule (最小点覆盖 && 二分图最大匹配)

鏈接: http://poj.org/problem?id=1325 Description As we all know, machine scheduling is a very class...

POJ 1325 Machine Schedule (二分图最小点集覆盖 匈牙利算法)

POJ 1325 Machine Schedule (二分图最小点集覆盖 匈牙利算法)

Poj 1325 Machine Schedule【二分匹配-------最小点覆盖】

Machine Schedule Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14439 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 1325 Machine Schedule 二分图 最小点覆盖
举报原因:
原因补充:

(最多只允许输入30个字)