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\n",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\n",ans);
    }
    return 0;
}


 

 

 

posted @ 2013-07-26 19:10  jlins  阅读(187)  评论(0编辑  收藏  举报