poj 2239 Selecting Courses

继续复习

二分图

题意:比较裸的二分图,输入n,表示n个不同的课程,下面n行,每行首先是m,表示后面跟着m对信息,每对信息为(p,q),表示在星期p的第q节上这节课,(一周7天,一天12节课)。问你怎么匹配,可以让这个人一周上最多的课。

建立二分图,X为时间,[0,83],Y为课程,[0,n-1],然后有向边Y--->X,进行匈牙利一次即可

#include <cstdio>
#include <cstring>
#define N 410
#define M 50500

int n,tot;
int match[N];
int head[N];
struct edge
{
    int u,v,next;
}e[M];
bool vis[N];

void add(int u ,int v)
{
    e[tot].u = u; e[tot].v = v;
    e[tot].next = head[u]; head[u] = tot++;
}

int dfs(int u)
{
    for(int k=head[u]; k!=-1; k=e[k].next)
    {
        int v = e[k].v;
        if(!vis[v])
        {
            vis[v] = true;
            if(match[v] == -1 || dfs(match[v]))
            {
                match[v] = u;
                return 1;
            }
        }
    }
    return 0;
}

void solve()
{
    int res = 0;
    memset(match,-1,sizeof(match));
    for(int i=0; i<n; i++)
    {
        memset(vis,false,sizeof(vis));
        res += dfs(i);
    }
    printf("%d\n",res);
//    for(int i=0; i<84; i++)
//        printf("%d[%d]\n",i,match[i]);
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        tot = 0;
        memset(head,-1,sizeof(head));
        for(int i=0; i<n; i++)
        {
            int m,p,q,time;
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d%d",&p,&q);
                time = p*12+q-13;
                add(i,time);
            }
        }
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/scau20110726/p/3071928.html