POJ2239二分匹配

   开始以为是最长路,想着把每一门课程的每一节课时作为一个点去建有向图。。。然后写的时候发现点太多了(300*7*12)建图特麻烦,就果断放弃了这个思路。

   然后开始用排除法来想用什么算法合适,没环不可能缩点,源点汇点非常不明显不像最大流,什么最小生成树啊就更不可能了。那就是二分了,可是怎么分呢?我就想输出的是最多能上多少门课,答案肯定小于等于n(课程数目),给你了每门课程的所有时间,哎呀!用每门课程去匹配一个合适的时间不就完了吗?最大匹配数一定小于等于n。

   上代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<vector>
 5 #define maxn 80000
 6 using namespace std;
 7 
 8 int n;
 9 vector<int> g[maxn];
10 int link[maxn],vis[maxn];
11 
12 int dfs(int x)
13 {
14     for(int i=0;i<g[x].size();i++)
15     {
16         int e = g[x][i];
17         if(!vis[e])
18         {
19             vis[e]=1;
20             if(link[e]==-1||dfs(link[e]))
21                {
22                    link[e]=x;
23                    return true;
24                }
25         }
26     }
27     return false;
28 }
29 void solve()
30 {
31     int sum=0;
32     memset(link,-1,sizeof(link));
33     for(int i=1;i<=n;i++)
34     {
35         memset(vis,0,sizeof(vis));
36         if(dfs(i)) sum++;
37     }
38     printf("%d
",sum);
39 }
40 int main()
41 {
42     while(scanf("%d",&n)!=EOF)
43     {
44         for(int k=1;k<=n;k++)
45             g[k].clear();
46         for(int i=1;i<=n;i++)
47         {
48             int m;
49             scanf("%d",&m);
50             for(int j=1;j<=m;j++)
51             {
52                 int a,b;
53                 scanf("%d%d",&a,&b);
54                 g[i].push_back(12*(a-1)+b);
55             }
56         }
57         solve();
58     }
59     return 0;
60 }
View Code
原文地址:https://www.cnblogs.com/liboyan/p/4423323.html