记录编号 228585 评测结果 AAAAAAAAAA
题目名称 [Ural 1099] 工作安排 最终得分 100
用户昵称 Gravatar铁策 是否通过 通过
代码语言 C++ 运行时间 0.033 s
提交时间 2016-02-19 13:39:51 内存使用 0.26 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <vector>
  5. #include <algorithm>
  6. using namespace std;
  7. #define MAXN 501
  8. int father[MAXN];
  9. int getfather(int x)
  10. {
  11. if (father[x]==x)
  12. return x;
  13. else
  14. return (father[x]=getfather(father[x]));
  15. }
  16. void uni(int a,int b)
  17. {
  18. a=getfather(a);
  19. b=getfather(b);
  20. if (a!=b)
  21. father[a]=b;
  22. }
  23. int n,m,t;
  24. vector<int> edge[MAXN];
  25. int queue[MAXN]={0},rear;
  26. int match[MAXN]={0},next[MAXN],mark[MAXN],vis[MAXN];
  27. inline int lca(int x,int y)
  28. {
  29. static int t=0;
  30. t++;
  31. while (true)
  32. {
  33. if (x)
  34. {
  35. x=getfather(x);
  36. if (vis[x]==t)
  37. return x;
  38. vis[x]=t;
  39. if (match[x])
  40. x=next[match[x]];
  41. else
  42. x=0;
  43. }
  44. swap(x,y);
  45. }
  46. }
  47. void group(int a,int p)
  48. {
  49. while (a!=p)
  50. {
  51. int b=match[a],c=next[b];
  52. if (getfather(c)!=p)
  53. next[c]=b;
  54. if (mark[b]==2)
  55. {
  56. queue[rear++]=b;
  57. mark[b]=1;
  58. }
  59. if (mark[c]==2)
  60. {
  61. queue[rear++]=c;
  62. mark[c]=1;
  63. }
  64. uni(a,b);
  65. uni(b,c);
  66. a=c;
  67. }
  68. }
  69. void aug(int s)
  70. {
  71. memset(next,0,sizeof(next));
  72. memset(mark,0,sizeof(mark));
  73. memset(vis,0,sizeof(vis));
  74. for (int i=1;i<=n;i++)
  75. father[i]=i;
  76. mark[s]=1;
  77. queue[0]=s;
  78. rear=1;
  79. for (int front=0;!match[s] && front<rear;front++)
  80. {
  81. int x=queue[front];
  82. for (int j=0;j<(int)edge[x].size();j++)
  83. {
  84. int y=edge[x][j];
  85. if (match[x]==y || getfather(x)==getfather(y) || mark[y]==2)
  86. continue;
  87. if (mark[y]==1)
  88. {
  89. int r=lca(x,y);
  90. if (getfather(x)!=r)
  91. next[x]=y;
  92. if (getfather(y)!=r)
  93. next[y]=x;
  94. group(x,r);
  95. group(y,r);
  96. }
  97. else if (!match[y])
  98. {
  99. next[y]=x;
  100. for (int u=y;u;)
  101. {
  102. int v=next[u];
  103. int t=match[v];
  104. match[v]=u;
  105. match[u]=v;
  106. u=t;
  107. }
  108. break;
  109. }
  110. else
  111. {
  112. next[y]=x;
  113. queue[rear++]=match[y];
  114. mark[match[y]]=1;
  115. mark[y]=2;
  116. }
  117. }
  118. }
  119. }
  120. int main()
  121. {
  122. freopen("WorkScheduling.in","r",stdin);
  123. freopen("WorkScheduling.out","w",stdout);
  124. scanf("%d",&n);
  125. int x,y;
  126. while (scanf("%d%d",&x,&y)==2)
  127. {
  128. edge[x].push_back(y);
  129. edge[y].push_back(x);
  130. }
  131. for (int i=1;i<=n;i++)
  132. if (!match[i])
  133. aug(i);
  134. int sum=0;
  135. for (int i=1;i<=n;i++)
  136. if (match[i])
  137. sum++;
  138. cout<<sum<<endl;
  139. bool vised[255]={0};
  140. for (int i=1;i<=n;i++)
  141. {
  142. if (!vised[i] && match[i])
  143. {
  144. cout<<i<<" "<<match[i]<<endl;
  145. vised[i]=vised[match[i]]=1;
  146. }
  147. }
  148. return 0;
  149. }
  150.