记录编号 389343 评测结果 AAAAAAAAAA
题目名称 [网络流24题] 骑士共存 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 0.669 s
提交时间 2017-03-31 09:48:51 内存使用 1.40 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cstdarg>
  5. #include <list>
  6. #include <queue>
  7. #include <vector>
  8. #include <algorithm>
  9. #include <cctype>
  10. using namespace std;
  11. #define MAXN 40233
  12. namespace IO{
  13. char buf[1<<18], *fs, *ft;
  14. inline char readc(){
  15. return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<18,stdin)),fs==ft)?EOF:*fs++;
  16. }
  17. inline int readint(){
  18. char c; int r;
  19. while(c = readc()){if(c >= '0' && c <= '9'){r = c^0x30;break;}}
  20. while(isdigit(c = readc()))r = (r<<3)+(r<<1)+(c^0x30);
  21. return r;
  22. }
  23. inline int read_string(char *str){
  24. int len = 1;char c;
  25. while(!isalpha(c = readc()));str[0] = c;
  26. while(isalpha(c = readc()))str[len++] = c;
  27. str[len] = 0;
  28. return len;
  29. }
  30. };using IO::read_string; using IO::readint;
  31. struct edge{
  32. int from, to, rem;
  33. }; vector<edge> edges;
  34. vector<int> G[MAXN];
  35. void addedge(int u, int v, int f){
  36. edges.push_back((edge){u, v, f});
  37. edges.push_back((edge){v, u, 0});
  38. int k = edges.size();
  39. G[u].push_back(k-2); G[v].push_back(k-1);
  40. }
  41. int dist[MAXN];
  42. int cure[MAXN];
  43. bool vis[MAXN];
  44. int s, t;
  45. bool bfs(){
  46. memset(vis, false, sizeof(vis));
  47. queue<int> q;
  48. q.push(s);
  49. vis[s] = true, dist[s] = 0;
  50. while(!q.empty()){
  51. int u = q.front(); q.pop();
  52. for(int i = 0; i < G[u].size(); i++){
  53. edge &e = edges[G[u][i]];
  54. if(e.rem > 0 && !vis[e.to]){
  55. vis[e.to] = true;
  56. q.push(e.to);
  57. dist[e.to] = dist[u]+1;
  58. }
  59. }
  60. }
  61. return vis[t];
  62. }
  63. int dfs(int u, int f){
  64. if(u == t || !f)return f;
  65. int tot = 0;
  66. for(int &i = cure[u]; i < G[u].size(); i++){
  67. edge &e = edges[G[u][i]];
  68. int next;
  69. if(dist[e.to] == dist[u]+1 && (next = dfs(e.to, min(f, e.rem))) > 0){
  70. f -= next, tot += next, edges[G[u][i]^1].rem += next, e.rem -= next;
  71. if(!f)break;
  72. }
  73. }
  74. return tot;
  75. }
  76. int maxflow(){
  77. int f = 0;
  78. while(bfs())memset(cure, 0, sizeof(cure)),
  79. f += dfs(s, 0x7fffffff);return f;
  80. }
  81. bool rect[201][201];
  82. int n, m;
  83. inline int getv(int x, int y){
  84. return (x-1)*n+y;
  85. }
  86. int dx[] = {-2,-1,1,2,2,1,-1,-2};
  87. int dy[] = {1,2,2,1,-1,-2,-2,-1};
  88. int main(){
  89. freopen("knight.in", "r", stdin);
  90. freopen("knight.out", "w", stdout);
  91. n = readint(); m = readint();
  92. while(m--){
  93. int x = readint(); int y = readint();
  94. rect[x][y] = true;
  95. }
  96. int tot = 0;
  97. s = 0, t = n*n+1;
  98. for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++){
  99. if(rect[i][j])continue; tot++;
  100. if((i+j)&1)addedge(getv(i, j), t, 1); //white
  101. else addedge(s, getv(i, j), 1); //black
  102. }
  103. for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++){
  104. if((i+j)&1 || rect[i][j])continue;
  105. for(int k = 0; k < 8; k++){
  106. int nx = i+dx[k], ny = j+dy[k];
  107. if(!(nx < 1 || nx > n || ny < 1 || ny > n || rect[nx][ny]))//continue;
  108. addedge(getv(i, j), getv(nx, ny), 0x7fffffff);
  109. }
  110. }
  111. printf("%d\n", tot-maxflow());
  112. return 0;
  113. }