HDU 3468 Treasure Hunting(BFS+网络流之最大流)
题目地址:HDU 3468
这道题的关键在于能想到用网络流。然后还要想到用bfs来标记最短路中的点。
首先标记方法是,对每个集合点跑一次bfs,记录全部点到该点的最短距离。然后对于随意一对起始点来说,仅仅要这个点到起点的最短距离+该点到终点的最短距离==起点到终点的最短距离,就说明这点在某条从起点到终点的最短路上。
然后以集合点建X集,宝物点建Y集构造二分图,将从某集合点出发的最短路中经过宝物点与该集合点连边。剩下的用二分匹配算法或最大流算法都能够。(为什么我的最大流比二分匹配跑的还要快。。。。。。。)。
题目有一点须要注意,就是当从集合点i到i+1没有路的时候,要输出-1.
代码例如以下:
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #include <ctype.h>
- #include <queue>
- #include <map>
- #include<algorithm>
- using namespace std;
- const int INF=0x3f3f3f3f;
- int head[12001], source, sink, nv, cnt;
- int cur[12001], num[12001], pre[12001], d[12001];
- int d1[60][12001], dd[60], vis[101][101], n, m, goad[12000], id[110][110], tot;
- int jx[]= {0,0,1,-1};
- int jy[]= {1,-1,0,0};
- char mp[110][110];
- struct node
- {
- int u, v, cap, next;
- } edge[10000000];
- void add(int u, int v, int cap)
- {
- edge[cnt].v=v;
- edge[cnt].cap=cap;
- edge[cnt].next=head[u];
- head[u]=cnt++;
- edge[cnt].v=u;
- edge[cnt].cap=0;
- edge[cnt].next=head[v];
- head[v]=cnt++;
- }
- void bfs()
- {
- memset(d,-1,sizeof(d));
- memset(num,0,sizeof(num));
- queue<int>q;
- q.push(sink);
- d[sink]=0;
- num[0]=1;
- while(!q.empty())
- {
- int u=q.front();
- q.pop();
- for(int i=head[u];i!=-1;i=edge[i].next)
- {
- int v=edge[i].v;
- if(d[v]==-1)
- {
- d[v]=d[u]+1;
- num[d[v]]++;
- q.push(v);
- }
- }
- }
- }
- void isap()
- {
- memcpy(cur,head,sizeof(cur));
- bfs();
- int flow=0, u=pre[source]=source, i;
- while(d[source]<nv)
- {
- if(u==sink)
- {
- int f=INF, pos;
- for(i=source;i!=sink;i=edge[cur[i]].v)
- {
- if(f>edge[cur[i]].cap)
- {
- f=edge[cur[i]].cap;
- pos=i;
- }
- }
- for(i=source;i!=sink;i=edge[cur[i]].v)
- {
- edge[cur[i]].cap-=f;
- edge[cur[i]^1].cap+=f;
- }
- flow+=f;
- u=pos;
- }
- for(i=cur[u];i!=-1;i=edge[i].next)
- {
- if(d[edge[i].v]+1==d[u]&&edge[i].cap) break;
- }
- if(i!=-1)
- {
- cur[u]=i;
- pre[edge[i].v]=u;
- u=edge[i].v;
- }
- else
- {
- if(--num[d[u]]==0) break;
- int mind=nv;
- for(i=head[u];i!=-1;i=edge[i].next)
- {
- if(mind>d[edge[i].v]&&edge[i].cap)
- {
- mind=d[edge[i].v];
- cur[u]=i;
- }
- }
- d[u]=mind+1;
- num[d[u]]++;
- u=pre[u];
- }
- }
- printf("%d\n",flow);
- }
- int getid(char c)
- {
- if(c>='A'&&c<='Z')
- return c-'A'+1;
- else if(c>='a'&&c<='z')
- return c-'a'+27;
- else
- return 0;
- }
- void bfs(int x, int y)
- {
- int i;
- queue<int>q;
- q.push(x*m+y);
- memset(vis,0,sizeof(vis));
- vis[x][y]=1;
- d1[id[x][y]][x*m+y]=0;
- while(!q.empty())
- {
- int u=q.front();
- q.pop();
- int a=u/m;
- int b=u%m;
- for(i=0; i<4; i++)
- {
- int c=a+jx[i];
- int d=b+jy[i];
- if(c>=0&&c<n&&d>=0&&d<m&&!vis[c][d]&&mp[c][d]!='#')
- {
- vis[c][d]=1;
- d1[id[x][y]][c*m+d]=d1[id[x][y]][a*m+b]+1;
- q.push(c*m+d);
- if(id[c][d]==id[x][y]+1)
- {
- dd[id[x][y]]=d1[id[x][y]][c*m+d];
- }
- }
- }
- }
- }
- int main()
- {
- int i, j, nu;
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- memset(head,-1,sizeof(head));
- memset(d1,INF,sizeof(d1));
- memset(dd,INF,sizeof(dd));
- cnt=0;
- nu=0;
- tot=0;
- for(i=0; i<n; i++)
- {
- scanf("%s",mp[i]);
- for(j=0; j<m; j++)
- {
- if(mp[i][j]=='*')
- {
- goad[nu++]=i*m+j;
- }
- id[i][j]=getid(mp[i][j]);
- if(id[i][j])
- tot++;
- }
- }
- for(i=0; i<n; i++)
- {
- for(j=0; j<m; j++)
- {
- if(id[i][j])
- {
- bfs(i,j);
- }
- }
- }
- for(i=1; i<tot; i++)
- {
- if(dd[i]==INF)
- {
- printf("-1\n");
- break;
- }
- }
- if(i<tot)
- continue ;
- source=0;
- sink=tot+nu+1;
- nv=sink+1;
- for(i=1;i<tot;i++)
- {
- add(source,i,1);
- }
- for(i=1;i<=nu;i++)
- {
- add(i+tot,sink,1);
- }
- for(i=1; i<tot; i++)
- {
- for(j=0; j<nu; j++)
- {
- if(d1[i][goad[j]]+d1[i+1][goad[j]]==dd[i])
- {
- add(i,j+tot+1,1);
- }
- }
- }
- isap();
- }
- return 0;
- }
HDU 3468 Treasure Hunting(BFS+网络流之最大流)的更多相关文章
- 【网络流】 HDU 3468 Treasure Hunting
题意: A-Z&&a-z 表示 集结点 从A点出发经过 最短步数 走到下一个集结点(A的下一个集结点为B ,Z的下一个集结点为a) 的路上遇到金子(*)则能够捡走(一个点仅仅能捡一次) ...
- HDU 3338 Kakuro Extension (网络流,最大流)
HDU 3338 Kakuro Extension (网络流,最大流) Description If you solved problem like this, forget it.Because y ...
- HDU 4280 Island Transport(网络流,最大流)
HDU 4280 Island Transport(网络流,最大流) Description In the vast waters far far away, there are many islan ...
- HDU 3641 Treasure Hunting(阶乘素因子分解+二分)
题目链接:pid=3641">传送门 题意: 求最小的 ( x! ) = 0 mod (a1^b1*a2^b2...an^bn) 分析: 首先吧a1~an进行素因子分解,然后统计下每一 ...
- hdu 3641 Treasure Hunting 强大的二分
/** 大意:给定一组ai,bi . m = a1^b1 *a2^b2 * a3^ b3 * a4^b4*...*ai^bi 求最小的x!%m =0 思路: 将ai 质因子分解,若是x!%m=0 那么 ...
- HDU 3605Escape(缩点+网络流之最大流)
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3605 本来打算昨天写两道题的,结果这个题卡住了,最后才发现是最后的推断条件出错了,推断满流的条件应该是 ...
- HDU 3416 Marriage Match IV (最短路径,网络流,最大流)
HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...
- HDU 3081 Marriage Match II (网络流,最大流,二分,并查集)
HDU 3081 Marriage Match II (网络流,最大流,二分,并查集) Description Presumably, you all have known the question ...
- HDU 3605 Escape (网络流,最大流,位运算压缩)
HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...
随机推荐
- jenkins中Deploy to container Plugin插件发布配置
参数详解: 第一项(WAR/EAR files):是war包的相对路径(相对于工作区路径,即在工作区中war包的相对路径.)如我的maven执行完成之后会在工作区的target目录下生成项目.war, ...
- 设置windows窗口半透明(使用SetLayeredWindowAttributes API函数)
所需函数原型:BOOL WINAPI SetLayeredWindowAttributes(HWND hWnd, COLORREFcrKey, BYTE bAlpha, DWORD flag); ...
- 图片和提交servlet的相对和绝对路径
xx.jsp在根目录下,图片的路径为:<img height="33" src="images/enter.gif" width="148&qu ...
- SQL server指定随机数范围
declare @randnum int=0declare @startnum int =0declare @endnum int=0 set @startnum = 150 set @endnum ...
- linux 和unix 的区别
Linux与Unix的区别 某些PC机的Unix和Linux在实现方面相类似.几乎所有的商业Unix版本都基本支持同样的软件.程序设计环境和网络特性.然而,Linux和Unix的商业版本依然存在许多 ...
- Spring、Bean 的作用域
Singleton作用域(默认) 当一个bean的作用域为singleton,那么Spring Ioc容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则 ...
- hdu 2604 Queuing(矩阵快速幂乘法)
Problem Description Queues and Priority Queues are data structures which are known to most computer ...
- Mysql 计算时间间隔函数
#计算两个时间的间隔 #计算间隔天数 select TIMESTAMPDIFF(day,'2014-06-01',date(now())) #计算间隔月数 select TIMESTAMPDIFF(m ...
- CSS ::before 和 ::after 伪元素用法
CSS 有两个说不上常用的伪类 :before 和 :after,偶尔会被人用来添加些自定义格式什么的,但是它们的功用不仅于此.前几天发现了 Creative Link Effects 这个非常有意思 ...
- js的this几种用法
1.普通的函数调用 此时指的是全局对象 function aaa(){ this.x=1;}aaa();alert(x) 2.对象内的方法this调用 此时指的是上一级对象 var aaa={ zz: ...