继续复习
二分图
题意:比较裸的二分图,输入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; }