zoukankan      html  css  js  c++  java
  • poj 3894 System Engineer (二分图最大匹配--匈牙利算法)

    System Engineer
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 507   Accepted: 217

    Description

    Bob is a skilled system engineer. He is always facing challenging problems, and now he must solve a new one. He has to handle a set of servers with differing capabilities available to process job requests from persistent sources - jobs that need to be processed over a long or indefinite period of time. A sequence of persistent job requests arrives revealing a subset of servers capable of servicing their request. A job is processed on a single server and a server processes only one job. Bob has to schedule the maximum number of jobs on the servers. For example, if there are 2 jobs j1, j2 and 2 servers s1, s2, job j1 requiring the server s1, and job j2 requiring also the server s1. In this case Bob can schedule only one job. Can you help him?
    In the general case there are n jobs numbered from 0 to n-1, n servers numbered from n to 2*n-1, and a sequence of job requests. The problem asks to find the maximum number of jobs that can be processed.

    Input

    The program input is at most 1 MB. Each data set in the file stands for a particular set of jobs. A data set starts with the number n (n <= 10000) of jobs, followed by the list of required servers for each job, in the format: jobnumber: (nr_servers) s1 ... snr_servers The program prints the maximum number of jobs that can be processed.
    White spaces can occur freely in the input. The input data are correct and terminate with an end of file.

    Output

    For each set of data the program prints the result to the standard output from the beginning of a line.

    Sample Input

    2 
    0: (1) 2 
    1: (1) 2 
    1 
    0: (1) 1

    Sample Output

    1
    1

    Hint

    There are two data sets. In the first case, the number of jobs n is 2, numbered 0 and 1. The sequence of requests for job 0 is: 0: (1) 2, meaning that job 0 requires 1 sever, the server numbered 2. The sequence of requests for job 1 is: 1: (1) 2, meaning that job 1 requires 1 sever, the server numbered 2. The result for the data set is the length of the maximum number of scheduled jobs, 1.

    Source

    Southeastern European Regional Programming Contest 2009

     

    题意:分配工作。一个工作和一个人一一对应。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    struct edge
    {
        int to,next;
    }e[100000];
    int index;
    
    bool visit[10010];   //记录v2中的某个点是否被搜索过
    int match[10010];    //记录与V2中的点匹配的点的编号
    int head[10010];
    int m,cnt;   
    
    //向图中加边,注意加入的是有向边
    //u为v的后继节点即v------>u
    void addedge(int u,int v)
    {
        e[index].to=v;
        e[index].next=head[u];
        head[u]=index;
        index++;
    }
    
    //匈牙利算法(邻接表存图)
    bool dfs(int u)
    {
        int i,v;
        for(i=head[u];i;i=e[i].next)
        {
            v=e[i].to;
            if(!visit[v])    //如果节点u与v相邻且未被查找过
            {
                visit[v]=true;    //标记v已查找过
                if(match[v]==-1||dfs(match[v]))    //如果v未在前一个匹配M中,或者v在匹配M中,但是
                {                                  //从与v相邻的节点出发可以有增广路径
                    match[v]=u;             //记录查找成功,更新匹配即"取反"
                    return true;            //返回查找成功。
                }
            }
        }
        return false;
    }
    
    void init()
    {
    	int aa,k,bb,i;
    	memset(head,0,sizeof(head));      //切记要初始化
        memset(e,0,sizeof(e));
        index=1;
    	for(i=1;i<=m;i++)
        {
            scanf("%d: (%d)",&aa,&k);
            //printf("ok: %d %d
    ",aa,k);
            while(k--)
            {
                scanf("%d",&bb);
                bb=bb-cnt+1;
                addedge(bb,aa+1);
            }
        }
    }
    
    int main()
    {
        int i;
        while(scanf("%d",&cnt)!=EOF)
        {
            m=cnt;
            init();
            int ans=0;
            memset(match,-1,sizeof(match));
            for(i=1;i<=cnt;i++)
            {
                memset(visit,0,sizeof(visit));    //清空上次搜索时的标记
                if(dfs(i))                 //从i节点尝试扩展
                   ans++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }


     

     

  • 相关阅读:
    oschina 终端/远程登录
    oschina文档/文本编辑
    oschinaIM/聊天/语音工具
    oschina浏览器开发
    oschina P2P/BT开源软件
    oschina图形和图像工具开源软件
    java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
    java之jvm学习笔记三(Class文件检验器)
    手把手教popupWindow从下往上,以达到流行效果
    java实现代理domino web邮件下载
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3220214.html
Copyright © 2011-2022 走看看