hdu 3729 最大匹配

  此题是我AC的HDU的201道题目。泪流满面啊!

  字典序最大(最小)真是个烦人的东西。

  学生i与其对应的分数区间的每个点连一条边。字典序最大,编号最大的学生开始匹配。

  HK无法AC啊,试了很久。我不会说,能过样例。

  最后用了DFS版的匈牙利算法过了。人们说这个代码简洁。不过我一般都用HK,时间复杂度低。今天发现了这个,还是有收获的。下次什么字典序,就用匈牙利。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=65,M=110050,INF=0x3f3f3f3f;
 8 bool bmask[M];
 9 int cx[N],cy[M];
10 int nx,ans;
11 vector<int> bmap[N];
12 int findpath(int u)
13 {
14     int i,j;
15     for(j=0;j<bmap[u].size();j++)
16     {
17         i=bmap[u][j];
18         if(!bmask[i])
19         {
20             bmask[i]=1;
21             if(cy[i]==-1||findpath(cy[i]))
22             {
23                 cy[i]=u; cx[u]=i;
24                 return 1;
25             }
26         }
27     }
28     return 0;
29 }
30 void maxmatch()
31 {
32     int i ,j;
33     ans=0;
34     memset(cx,-1,sizeof(cx));
35     memset(cy,-1,sizeof(cy));
36     for(i=nx;i>=1;i--)
37     {
38         if(cx[i]==-1)
39         {
40             memset(bmask,0,sizeof(bmask));
41             ans+=findpath(i);
42         }
43     }
44 }
45 int main()
46 {
47     //freopen("test.txt","r",stdin);
48     int cas,i,j,k,n,a,b;
49     scanf("%d",&cas);
50     while(cas--)
51     {
52         scanf("%d",&n);
53         for(i=1;i<=n;i++)
54         {
55             bmap[i].clear();
56             scanf("%d%d",&a,&b);
57             for(k=a;k<=b;k++)
58             bmap[i].push_back(k);
59         }
60         nx=n;
61         maxmatch();
62         printf("%d\n",ans);
63         for(i=1;i<=nx;i++)
64         {
65             if(cx[i]!=-1)
66             {
67                 printf("%d",i);
68                 ans--;
69                 if(ans) printf(" ");
70                 else printf("\n");
71             }
72         }
73     }
74     return 0;
75 }
View Code

 

转载于:https://www.cnblogs.com/Potato-lover/p/3987427.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值