题意:见挑战230页

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <vector>
  7. #include <queue>
  8. #include <map>
  9. #include <algorithm>
  10. #include <set>
  11. using namespace std;
  12. #define MM(a) memset(a,0,sizeof(a))
  13. typedef long long ll;
  14. typedef unsigned long long ULL;
  15. const int mod = 1000000007;
  16. const double eps = 1e-10;
  17. const int inf = 0x3f3f3f3f;
  18. const int big=50000;
  19. int max(int a,int b) {return a>b?a:b;};
  20. int min(int a,int b) {return a<b?a:b;};
  21. int n,m,x,y;
  22. vector<int> G[100005];
  23. vector<int> dx,dy,px,py;
  24. char field[15][15];
  25. int xx[4]={-1,1,0,0},yy[4]={0,0,1,-1};
  26. int sroad[15][15][15][15],dist[15][15];
  27. int used[30000],match[1000000];
  28. void add_edge(int u,int v)
  29. {
  30. G[u].push_back(v);
  31. G[v].push_back(u);
  32. }
  33. void bfs(int x,int y)
  34. {
  35. memset(dist,-1,sizeof(dist));
  36. dist[x][y]=0;
  37. queue<int> qx,qy;
  38. qx.push(x);
  39. qy.push(y);
  40. while(!qx.empty())
  41. {
  42. int sx=qx.front();
  43. int sy=qy.front();
  44. for(int i=0;i<=3;i++)
  45. {
  46. int tx=sx+xx[i],ty=sy+yy[i];
  47. if(tx>=0&&tx<n&&ty>=0&&ty<m)
  48. if(field[tx][ty]=='.'&&dist[tx][ty]<0)
  49. {
  50. dist[tx][ty]=dist[sx][sy]+1;
  51. sroad[x][y][tx][ty]=dist[tx][ty];
  52. qx.push(tx);
  53. qy.push(ty);
  54. }
  55. }
  56. qx.pop();
  57. qy.pop();
  58. }
  59. }
  60. int dfs(int u)
  61. {
  62. used[u]=1;
  63. for(int i=0;i<G[u].size();i++)
  64. {
  65. int v=G[u][i],w=match[v];
  66. if(w<0||!used[w]&&dfs(w))
  67. {
  68. match[u]=v;
  69. match[v]=u;
  70. return 1;
  71. }
  72. }
  73. return 0;
  74. }
  75. int pipei(int t)
  76. {
  77. int res=0;
  78. for(int i=0;i<dx.size();i++)
  79. {
  80. int u=i+t*dx.size();
  81. if(match[u]<0)
  82. {
  83. memset(used,0,sizeof(used));
  84. if(dfs(u))
  85. res++;
  86. }
  87. }
  88. return res;
  89. }
  90. int num(int t)
  91. {
  92. for(int i=0;i<px.size();i++)
  93. for(int j=0;j<dx.size();j++)
  94. {
  95. int renx=px[i],reny=py[i];
  96. int menx=dx[j],meny=dy[j];
  97. if(sroad[menx][meny][renx][reny]<=t)
  98. add_edge(t*dx.size()+j,(n*m+10)*dx.size()+10+i);
  99. }
  100. return pipei(t);
  101. }
  102. void solve()
  103. {
  104. memset(match,-1,sizeof(match));
  105. int ans=0;
  106. for(int t=0;t<=n*m+3;t++)
  107. {
  108. ans+=num(t);
  109. if(ans>=px.size())
  110. {
  111. cout<<t<<endl;
  112. return;
  113. }
  114. }
  115. cout<<"impossible"<<endl;
  116. }
  117. int main()
  118. {
  119. int cas;
  120. cin>>cas;
  121. while(cas--)
  122. {
  123. scanf("%d %d",&n,&m);
  124. dx.clear();dy.clear();
  125. px.clear();py.clear();
  126. for(int i=0;i<=100005;i++)
  127. G[i].clear();
  128. for(int i=0;i<n;i++)
  129. scanf("%s",field[i]);
  130. memset(sroad,inf,sizeof(sroad));
  131. for(int i=0;i<n;i++)
  132. {
  133. for(int j=0;j<m;j++)
  134. if(field[i][j]=='D')
  135. {
  136. dx.push_back(i);
  137. dy.push_back(j);
  138. bfs(i,j);
  139. }
  140. else if(field[i][j]=='.')
  141. {
  142. px.push_back(i);
  143. py.push_back(j);
  144. }
  145. }
  146. solve();
  147. }
  148. return 0;
  149. }

 分析:强大的二分匹配(因为一个门一时刻只能通过一个人),这是我的做法,用的是枚举时间

不过看挑战上是直接枚举时间和门组成的二元组的点,每次dfs该点,进行一次匈牙利算法,最后再算出时间

好像程序可以简化一点,不过我的这份代码的效率比较高,排名在270多名,不过开的数组大小很关键,在这个上wa了很多次。

下面是wa代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <vector>
  7. #include <queue>
  8. #include <map>
  9. #include <algorithm>
  10. #include <set>
  11. using namespace std;
  12. #define MM(a) memset(a,0,sizeof(a))
  13. typedef long long ll;
  14. typedef unsigned long long ULL;
  15. const int mod = 1000000007;
  16. const double eps = 1e-10;
  17. const int inf = 0x3f3f3f3f;
  18. const int big=50000;
  19. int max(int a,int b) {return a>b?a:b;};
  20. int min(int a,int b) {return a<b?a:b;};
  21. int n,m,x,y;
  22. vector<int> G[1005];
  23. vector<int> dx,dy,px,py;
  24. char field[15][15];
  25. int xx[4]={-1,1,0,0},yy[4]={0,0,1,-1};
  26. int sroad[15][15][15][15],dist[15][15];
  27. int used[150],match[10000];
  28. void add_edge(int u,int v)
  29. {
  30. G[u].push_back(v);
  31. G[v].push_back(u);
  32. }
  33. void bfs(int x,int y)
  34. {
  35. memset(dist,-1,sizeof(dist));
  36. dist[x][y]=0;
  37. queue<int> qx,qy;
  38. qx.push(x);
  39. qy.push(y);
  40. while(!qx.empty())
  41. {
  42. for(int i=0;i<=3;i++)
  43. {
  44. int tx=qx.front()+xx[i],ty=qy.front()+yy[i];
  45. if(tx>=0&&tx<n&&ty>=0&&ty<m)
  46. if(field[tx][ty]=='.'&&dist[tx][ty]<0)
  47. {
  48. dist[tx][ty]=dist[x][y]+1;
  49. sroad[x][y][tx][ty]=dist[tx][ty];
  50. qx.push(tx);
  51. qy.push(ty);
  52. }
  53. }
  54. qx.pop();
  55. qy.pop();
  56. }
  57. }
  58. int dfs(int u)
  59. {
  60. used[u]=1;
  61. for(int i=0;i<G[u].size();i++)
  62. {
  63. int v=G[u][i],w=match[v];
  64. //printf("%d %d\n",v,match[v]);
  65. // printf("match: %d w:%d\n",match[v],w);
  66. if(w<0||!used[w]&&dfs(w))
  67. {
  68. match[u]=v;
  69. match[v]=u;
  70. //printf("wwwww\n");
  71. return 1;
  72. }
  73. }
  74. return 0;
  75. }
  76. int pipei(int t)
  77. {
  78. int res=0;
  79. for(int i=0;i<dx.size();i++)
  80. {
  81. int u=i+t*dx.size();
  82. //printf("4 match:%d\n",match[0]);
  83. if(match[u]<0)
  84. {
  85. memset(used,0,sizeof(used));
  86. if(dfs(u))
  87. res++;
  88. }
  89. }
  90. // printf("res:%d\n",res);
  91. return res;
  92. }
  93. int num(int t)
  94. {
  95. for(int i=0;i<px.size();i++)
  96. for(int j=0;j<dx.size();j++)
  97. {
  98. int renx=px[i],reny=py[i];
  99. int menx=dx[j],meny=dy[j];
  100. if(sroad[menx][meny][renx][reny]<=t)
  101. add_edge(t*dx.size()+j,px.size()*dx.size()+10+i);
  102. }
  103. //printf("3 match:%d\n",match[0]);
  104. return pipei(t);
  105. }
  106. void solve()
  107. {
  108. memset(match,-1,sizeof(match));
  109. //printf("1 match:%d\n",match[0]);
  110. int ans=0;
  111. for(int t=0;t<=n*m+3;t++)
  112. {
  113. ans+=num(t);
  114. //cout<<t<<" "<<num(t)<<endl;
  115. //printf("2 match:%d\n",match[0]);
  116. if(ans>=px.size())
  117. {
  118. cout<<t<<endl;
  119. return;
  120. }
  121. }
  122. cout<<"impossible"<<endl;
  123. }
  124. int main()
  125. {
  126. int cas;
  127. cin>>cas;
  128. while(cas--)
  129. {
  130. scanf("%d %d",&n,&m);
  131. dx.clear();dy.clear();
  132. px.clear();py.clear();
  133. for(int i=0;i<=500;i++)
  134. G[i].clear();
  135. for(int i=0;i<n;i++)
  136. scanf("%s",field[i]);
  137. memset(sroad,inf,sizeof(sroad));
  138. for(int i=0;i<n;i++)
  139. {
  140. for(int j=0;j<m;j++)
  141. if(field[i][j]=='D')
  142. {
  143. dx.push_back(i);
  144. dy.push_back(j);
  145. bfs(i,j);
  146. }
  147. else if(field[i][j]=='.')
  148. {
  149. px.push_back(i);
  150. py.push_back(j);
  151. }
  152. }
  153. solve();
  154. }
  155. return 0;
  156. }

  

TTTTTTTTTTTTT poj 3057 Evacuation 二分图匹配+bfs的更多相关文章

  1. POJ 3057 Evacuation 二分图匹配

    每个门每个时间只能出一个人,那就把每个门拆成多个,对应每个时间. 不断增加时间,然后增广,直到最大匹配. //#pragma comment(linker, "/STACK:10240000 ...

  2. POJ 3057 Evacuation (二分匹配)

    题意:给定一个图,然后有几个门,每个人要出去,但是每个门每个秒只能出去一个,然后问你最少时间才能全部出去. 析:初一看,应该是像搜索,但是怎么保证每个人出去的时候都不冲突呢,毕竟每个门每次只能出一个人 ...

  3. POJ3057 Evacuation 二分图匹配+最短路

    POJ3057 Evacuation 二分图匹配+最短路 题目描述 Fires can be disastrous, especially when a fire breaks out in a ro ...

  4. POJ 3057 Evacuation(二分图匹配+BFS)

    [题目链接] http://poj.org/problem?id=3057 [题目大意] 给出一个迷宫,D表示门,.表示人,X表示不可通行, 每个门每时间单位只允许一个人通过, 每个人移动一格的为一时 ...

  5. [poj] 3057 Evacuation

    原题 题目大意 墙壁"X",空区域(都是人)".", 门"D". 人向门移动通过时视为逃脱,门每秒能出去一个人,人可以上下左右移动,墙阻止移 ...

  6. POJ 1274 裸二分图匹配

    题意:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶,告诉每头奶牛愿意产奶的牛棚编号,求出最多能分配到的牛栏的数量. 分析:直接二分图匹配: #include<stdio.h> #includ ...

  7. POJ 2446 Chessboard (二分图匹配)

    题意 在一个N*M的矩形里,用1*2的骨牌去覆盖该矩形,每个骨牌只能覆盖相邻的两个格子,问是否能把每个格子都盖住.PS:有K个孔不用覆盖. 思路 容易发现,棋盘上坐标和为奇数的点只会和坐标和为偶数的点 ...

  8. POJ 3057 Evacuation(二分匹配)

    分析: 这是一个时间和门的二元组(t,d)和人p匹配的问题,当我们固定d0时,(t,d0)匹配的人数和t具有单调性. t增加看成是多增加了边就行了,所以bfs处理出p到每个d的最短时间,然后把(t,d ...

  9. POJ 3057 Evacuation 二分+最大流

    Evacuation 题目连接: http://poj.org/problem?id=3057 Description Fires can be disastrous, especially when ...

随机推荐

  1. Go语言流程控制中的break,continue和goto(七)

    break(跳出循环) break用于跳出整个循环,如下: func main() { ;i<;i++{ { break } fmt.Println(i) } } // 0 1 2 3 代码里只 ...

  2. Junit+Mock单元测试

    项目用的是maven,所需jar包在pom.xml文件里面配置,单元测试要用的jar具体如下: <dependency> <groupId>junit</groupId& ...

  3. P3376 网络流-最大流模板题(Dinic+当前弧优化)

    (点击此处查看原题) Dinic算法 Dinic算法相对于EK算法,主要区别在于Dinic算法对图实现了分层,使得我们可以用一次bfs,一次dfs使得多条增广路得到增广 普通的Dinic算法已经可以处 ...

  4. windows terminal编译实录

    直接甩个大佬链接吧 https://www.bilibili.com/video/av52032233?t=835 安装过程中如果出问题了,靠搜索引擎解决下,微软或者vs的问题可以用biying搜索 ...

  5. 学习python基础规则

    前面应该是记流水账的方式,毕竟学习的内容不多无法产出什么有效的内容. 这两天从开始下载Python开始学习,一路顺畅冒的问题,直到开始学习python的游戏规则,严格缩进.注释及‘’的使用等感觉还不错 ...

  6. Java8 parallelStream浅析

    JAVA8中引入了lamda表达式和Stream接口.其丰富的API及强大的表达能力极大的简化代码,提升了效率,同时还通过parallelStream提供并发操作的支持,本文探讨parallelStr ...

  7. Android开发build出现java.lang.NumberFormatException: For input string: "tle 0x7f0800aa"错误的解决方案

    查看异常栈没有发现项目代码的问题,因为问题是出现在layout文件中. 全局查找tle这个,发现在某个layout文件中title一词被变成ti tle了,结果Android就xjb报错了. 参考

  8. redis的string和list

  9. mac 下安装mysql8.0

    有两种安装方式,一种是安装包安装,官网下载安装包,mysql8.0下载.mysql5.7安装: 这里记录brew安装: 1.brew uninstall mysql 卸载原有的: 2.brew ins ...

  10. deep_learning_tensorflow_get_variable()

    maxwell_tesla tf.get_variable函数的使用 tf.get_variable(name,  shape, initializer): name就是变量的名称,shape是变量的 ...