博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 2732 Leapin' Lizards(最大流)Mid-Central USA 2005
阅读量:4980 次
发布时间:2019-06-12

本文共 4462 字,大约阅读时间需要 14 分钟。

废话:

这道题不难,稍微构造一下图就可以套最大流的模板了。但是我还是花了好久才解决。一方面是最近确实非常没状态(托词,其实就是最近特别颓废,整天玩游戏看小说,没法静下心来学习),另一方面是不够细心,输出格式错了大意没有发现死一只和死多只之间的区别,卡在那里动不了。

 

题意:

在一张n*m的地图中,有一群蜥蜴,这群蜥蜴每次可以跳跃曼哈顿距离d(曼哈顿距离——dis(a, b) = |ax-bx|+|ay-by|,之后所有的距离都是曼哈顿距离),这些蜥蜴只能在地图上的一些柱子上跳跃。柱子i最多可以支持ki次经过。如果柱子i距离地图的边界的距离小于d那么蜥蜴可以从柱子i逃出升天。要求计算最后会有多少蜥蜴葬身图中。

 

输入:

第一行输入一个整数t,表示共有t组数据。

第二行输入两个整数nd,表示这组数据中地图有n行,蜥蜴一次最大跳跃距离d

接下来n行输入地图mp1,地图中的数字表示柱子可以经过的次数,0表示不可以经过。

接下来n行输入地图mp2,其中’.’表示空,’L’表示存在一只蜥蜴。

 

输出:

首先输出组数”Case #x: “,其中x表示第x组。

如果所有的蜥蜴都可以逃出,那么输出”no lizard was left behind.”

如果只有1只死去,那么输出”1 lizard was left behind.”

如果死去多于1只,那么输出”y lizards were left behind.”y表示死去的蜥蜴数量。

 

题解:

经过一番变化,我们可以构造出一张有向图,然后使用最大流来解决这个问题。

构造方法如下——

  1. 我们设源点为0,汇点为2*n*m+1(其中n为地图的行,m为地图的列),设图中两点p1p2的距离,即p1p2的有向边为mp[p1][p2]
  2. 将地图mp1中所有的点拆分成两个点,点pij拆分为mp[][]中的点i*m+j+1n*m+i*m+j+1,添加边mp[i*m+j+1][n*m+i*m+j+1] = mp1[i][j]。这是我们构造图mp中最关键的一步,正是因为有了这个有向边,我们才可以使用最大流来计算这个题。
  3. 对于地图mp1,枚举每个点pij,如果这个点距离地图边界的距离小于等于d,那么添加边mp[n*m+i*m+j+1][2*m*n+1] = mp1[i][j];同时枚举除pij以外的点pkl,如果pijpkl之间的距离小于等于d那么添加边mp[n*m+i*m+j+1][k*m+l+1] = max(mp1[i][j], mp1[k][l])
  4. 对于地图mp2,如果某个点pij 的值mp2[i][j] == ‘L’,那么构造边mp[0][i*m+j+1] = 1

然后计算从源点到汇点的最大流即可,我使用的Dinic算法。

 

具体见代码——

1 #include 
2 #include
3 #include
4 #include
5 #include
6 using namespace std; 7 8 const int N = 1000; 9 const int M = 100000010; 10 11 int dis[N]; 12 int cur[N]; 13 bool vis[N]; 14 char mp[2][30][30]; 15 int mp2[N][N]; 16 int n, m, d, t; 17 int ans, sum; 18 19 inline int Min(int x, int y) 20 { 21 return x < y ? x : y; 22 } 23 24 void init() 25 { 26 memset(mp, 0, sizeof(mp)); 27 memset(mp2, 0, sizeof(mp2)); 28 scanf("%d%d", &n, &d); 29 scanf("%s", mp[0][0]); 30 m = strlen(mp[0][0]); 31 sum = 0; 32 ans = 0; 33 for(int i = 1; i < n; i++) 34 { 35 scanf("%s", mp[0][i]); 36 } 37 for(int i = 0; i < n; i++) 38 { 39 for(int j = 0; j < m; j++) 40 { 41 for(int k = 0; k < n; k++) 42 { 43 for(int l = 0; l < m; l++) 44 { 45 int mid1 = abs(i-k)+abs(j-l); 46 if(mid1 <= d && i*m+j+1 != k*m+l+1) //点pij到点pkl之间距离小于等于d且不是同一点 47 { 48 int mid = Min(mp[0][i][j], mp[0][k][l]); 49 mp2[n*m+i*m+j+1][k*m+l+1] = mid; //从点pij到点pkl的边 50 } 51 } 52 } 53 mp2[i*m+j+1][n*m+i*m+j+1] = mp[0][i][j]-'0'; //从点pij到点pij的边 54 if(i < d || j < d || n-i <= d || m-j <= d) mp2[m*n+i*m+j+1][2*n*m+1] = mp[0][i][j]-'0'; //从点pij到汇点的边 55 } 56 } 57 for(int i = 0; i < n; i++) 58 { 59 scanf("%s", mp[1][i]); 60 for(int j = 0; j < m; j++) 61 { 62 if(mp[1][i][j] == 'L') 63 { 64 mp2[0][i*m+j+1] = 1; //从源点到点pij的边 65 sum++; 66 } 67 } 68 } 69 m = 2*n*m+1; 70 } 71 72 bool bfs() 73 { 74 memset(vis, 0, sizeof(vis)); 75 queue
que; 76 que.push(0); 77 dis[0] = 0; 78 vis[0] = 1; 79 while(!que.empty()) 80 { 81 int k = que.front(); 82 que.pop(); 83 for(int i = 0; i <= m; i++) 84 { 85 if(!vis[i] && mp2[k][i] > 0) 86 { 87 vis[i] = 1; 88 dis[i] = dis[k]+1; 89 que.push(i); 90 } 91 } 92 } 93 return vis[m]; 94 } 95 96 int dfs(int x, int val) 97 { 98 if(x == m || val == 0) return val; 99 int flow = 0, minn;100 for(int& i = cur[x]; i <= m; i++)101 {102 if(dis[x]+1 == dis[i] && (minn = dfs(i, Min(val, mp2[x][i]))) > 0)103 {104 mp2[x][i] -= minn;105 mp2[i][x] += minn;106 flow += minn;107 val -= minn;108 if(val == 0) break;109 }110 }111 return flow;112 }113 114 void work() //Dinic算法115 {116 while(bfs())117 {118 for(int i = 0; i <= m; i++) cur[i] = 1;119 ans += dfs(0, M);120 }121 }122 123 void outit(int tm)124 {125 sum -= ans;126 printf("Case #%d: ", tm);127 if(!sum) printf("no lizard was left behind.\n");128 else if(sum == 1) printf("1 lizard was left behind.\n");129 else printf("%d lizards were left behind.\n", sum);130 }131 132 int main()133 {134 //freopen("test.in", "r", stdin);135 scanf("%d", &t);136 for(int tm = 1; tm <= t; tm++)137 {138 init();139 work();140 outit(tm);141 }142 return 0;143 }
View Code

 

最大流入门——

 

转载于:https://www.cnblogs.com/mypride/p/4945949.html

你可能感兴趣的文章
Angular routing生成路由和路由的跳转
查看>>
第一周Access总结
查看>>
Project Euler欧拉计划
查看>>
yii 邮件发送
查看>>
一个翻译自VB6.0的验证码识别代码
查看>>
[UI] 精美UI界面欣赏[11]
查看>>
一个悲剧的问题,服务器控件还是少用吧
查看>>
JS总结
查看>>
UVM 之$cast
查看>>
HttpServletResponse
查看>>
Osmotic Study ----Mysql Safe
查看>>
SignalR使用笔记
查看>>
[清华集训2014]玛里苟斯(线性基+概率期望)
查看>>
Android屏幕density, dip等相关概念总结
查看>>
[你必须知道的.NET]第十五回:继承本质论
查看>>
.net 分布式架构之任务调度平台
查看>>
理解Linux系统负荷
查看>>
angular 初学(二)ng-class ng-disabled
查看>>
android 检查网络连接状态实现步骤
查看>>
网上商城(OnlineMall)用户模块
查看>>