二分图的最大匹配-hdu-3729-I'm Telling the Truth

来源:互联网 发布:天猫跟淘宝是什么关系 编辑:程序博客网 时间:2024/05/22 05:03
 

二分图的最大匹配-hdu-3729-I'm Telling the Truth

分类: 图论 96人阅读 评论(0) 收藏 举报
图论

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3729

题目意思:

有n个学生,老师询问每个学生的排名,每个学生都告诉了一个排名区间,求可能的最多的学生说实话的个数,以及那些学生的标号,有相同的则输出字典序最大的。

解题思路:

这题贪心只能求出个数,但要求字典序最大,则须用二分匹配。

将学生标号放到一个集合A里,另外一个集合B放排名。对于每个学生可能在的排名点,建一条边。从学生标号大的开始匹配。

代码

[cpp] view plaincopy
  1. #include<iostream>  
  2. #include<cmath>  
  3. #include<cstdio>  
  4. #include<sstream>  
  5. #include<cstdlib>  
  6. #include<string>  
  7. #include<cstring>  
  8. #include<algorithm>  
  9. #include<vector>  
  10. #include<map>  
  11. #include<set>  
  12. #include<stack>  
  13. #include<list>  
  14. #include<queue>  
  15. #include<ctime>  
  16. #include<bitset>  
  17. #define eps 1e-6  
  18. #define INF 0x3f3f3f3f  
  19. #define PI acos(-1.0)  
  20. #define ll __int64  
  21. #define LL long long  
  22. #define lson l,m,(rt<<1)  
  23. #define rson m+1,r,(rt<<1)|1  
  24. #define M 1000000007  
  25. #pragma comment(linker, "/STACK:1024000000,1024000000")  
  26. using namespace std;  
  27.   
  28. #define Maxn 65  
  29. #define Maxm 110000  
  30.   
  31. int cx[Maxn],cy[Maxm],nx,ny;  
  32. bool vis[Maxm];  
  33. vector<int>g[Maxn];  
  34.   
  35. int path(int u)  
  36. {  
  37.     for(int v=0;v<g[u].size();v++)  
  38.     {  
  39.         if(!vis[g[u][v]])   
  40.         {  
  41.             vis[g[u][v]]=true//从这个点找,要么找到对应的,要么找不到  
  42.             if(cy[g[u][v]]==-1||path(cy[g[u][v]]))  
  43.             {  
  44.                 cy[g[u][v]]=u;  
  45.                 cx[u]=g[u][v];  
  46.                 return 1;  
  47.             }  
  48.         }  
  49.     }  
  50.     return 0;  
  51. }  
  52. int MaxMatch()  
  53. {  
  54.     memset(cx,-1,sizeof(cx));  
  55.     memset(cy,-1,sizeof(cy));  
  56.   
  57.     int ans=0;  
  58.     for(int i=nx;i>=1;i--) //满足字典序最大  
  59.     {  
  60.         if(cx[i]==-1)  
  61.         {  
  62.             memset(vis,false,sizeof(vis));  
  63.             ans+=path(i);  
  64.         }  
  65.     }  
  66.     return ans;  
  67. }  
  68. int main()  
  69. {  
  70.     int t;  
  71.   
  72.     scanf("%d",&t);  
  73.     while(t--)  
  74.     {  
  75.         scanf("%d",&nx);  
  76.   
  77.         for(int i=1;i<=nx;i++)  
  78.         {  
  79.             g[i].clear();  
  80.             int a,b;  
  81.             scanf("%d%d",&a,&b);  
  82.             for(int j=a;j<=b;j++) //将所有的可能排名点建一条边  
  83.                 g[i].push_back(j);  
  84.         }  
  85.         int ans=MaxMatch();  
  86.         printf("%d\n",ans);  
  87.         for(int i=1;i<=nx;i++)  
  88.         {  
  89.             if(cx[i]!=-1)  
  90.             {  
  91.                 printf("%d",i);  
  92.                 ans--;  
  93.                 if(ans)  
  94.                     putchar(' ');  
  95.                 else  
  96.                     putchar('\n');  
  97.             }  
  98.         }  
  99.     }  
  100.    return 0;  
  101. }  
原创粉丝点击