[关闭]
@iamtts 2017-02-10T15:20:12.000000Z 字数 2040 阅读 863

寒假第六次训练-二分图

A - COURSES

题目大意:有n个学生和p门课,每门课程有0~n人参加,选定一人为课代表,课代表不能重复,问是否存在这样一群课代表使得每门课都有课代表

解题思路:匈牙利算法求二分图的最大匹配,若等于课程数则存在。

AC代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <string>
  4. #include <algorithm>
  5. #include <map>
  6. #include <vector>
  7. #include <cstring>
  8. #include <stack>
  9. using namespace std;
  10. #define MAXN 100005
  11. bool G[110][310];
  12. bool flag,visit[310];
  13. int match[310];
  14. int p,n;
  15. bool dfs(int u)
  16. {
  17. int v;
  18. for (v=1;v<=n;v++)
  19. {
  20. if (G[u][v] && !visit[v])
  21. {
  22. visit[v]=true;
  23. if (match[v]==-1 || dfs(match[v]))
  24. {
  25. match[v]=u;
  26. return true;
  27. }
  28. }
  29. }
  30. return false;
  31. }
  32. int main()
  33. {
  34. int t,i,j,k,temp,ans;
  35. scanf("%d",&t);
  36. while (t--)
  37. {
  38. ans=0;
  39. flag=true;
  40. memset(G,false,sizeof(G));
  41. memset(match,-1,sizeof(match));
  42. scanf("%d%d",&p,&n);
  43. for (i=1; i<=p; i++)
  44. {
  45. scanf("%d",&j);
  46. if (j==0)
  47. {
  48. flag=false;
  49. break;
  50. }
  51. while (j--)
  52. {
  53. scanf("%d",&temp);
  54. G[i][temp]=true;
  55. }
  56. }
  57. if (flag)
  58. {
  59. for (i=1; i<=p; i++)
  60. {
  61. memset(visit,false,sizeof(visit));
  62. if (dfs(i)) ans++;
  63. }
  64. if (ans==p) printf("YES\n");
  65. else printf("NO\n");
  66. }
  67. else printf("NO\n");
  68. }
  69. }

B - The Accomodation of Students

题目大意:有n个学生,m组学生相互认识,相互不认识的学生为一组,所有人分为两组,要求判断是否可以分为两组,若可以则把两组里互相认识的学生带入另一个房间,问最多可以带走多少组。

解题思路:先用染色法判断是否是二分图,然后用匈牙利算法求最大匹配

AC代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <string>
  4. #include <algorithm>
  5. #include <map>
  6. #include <vector>
  7. #include <cstring>
  8. #include <stack>
  9. using namespace std;
  10. #define MAXN 100005
  11. bool G[210][210];
  12. int color[210];
  13. bool flag,visit[210];
  14. int match[210];
  15. int m,n;
  16. bool paint(int i,int c)
  17. {
  18. int v;
  19. color[i]=c+1;
  20. for (v=1; v<=n; v++)
  21. {
  22. if (G[i][v])
  23. {
  24. if (color[v])
  25. {
  26. if (color[v]==color[i])
  27. return false;
  28. else continue;
  29. }
  30. else if (!paint(v,!(color[i]-1))) return false;
  31. }
  32. }
  33. return true;
  34. }
  35. bool dfs(int u)
  36. {
  37. int v;
  38. for (v=1; v<=n; v++)
  39. {
  40. if (G[u][v] && !visit[v])
  41. {
  42. visit[v]=true;
  43. if (match[v]==-1 || dfs(match[v]))
  44. {
  45. match[v]=u;
  46. return true;
  47. }
  48. }
  49. }
  50. return false;
  51. }
  52. int main()
  53. {
  54. int i,j,a,b,ans;
  55. while (scanf("%d%d",&n,&m)!=EOF)
  56. {
  57. ans=0;
  58. flag=true;
  59. memset(G,false,sizeof(G));
  60. memset(match,-1,sizeof(match));
  61. memset(color,0,sizeof(color));
  62. for (i=1; i<=m; i++)
  63. {
  64. scanf("%d%d",&a,&b);
  65. if (a!=b)
  66. {
  67. G[a][b]=true;
  68. G[b][a]=true;
  69. }
  70. }
  71. for (i=1;i<=n;i++)
  72. {
  73. if (!color[i]) flag=paint(i,0);
  74. if (!flag) break;
  75. }
  76. if (flag)
  77. {
  78. for (i=1; i<=n; i++)
  79. {
  80. if (color[i]==1)
  81. {
  82. memset(visit,false,sizeof(visit));
  83. if (dfs(i)) ans++;
  84. }
  85. }
  86. printf("%d\n",ans);
  87. }
  88. else printf("No\n");
  89. }
  90. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注