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\n",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

 

你可能感兴趣的:(poj)