POJ 3921 Destroying the bus stations
来源:互联网 发布:知乎 王家卫 章子怡 编辑:程序博客网 时间:2024/04/29 19:41
题目大意:
一个有向图有n个顶点(0 < n ≤ 50,编号为1 - n),m条边(0 < m ≤ 4,000),两个顶点之间可以有多条边,现要求删除最少的点使得从1号到n号顶点不存在长度≤k的路径(0 < k < 1,000),但是不能直接删掉1号和n号点。
现有多个测例,每个测例中都给出n、m、k,对于m条边都给出每条边的起始点序号和终止点序号,测例以n、m、k都等于0结束,对于每个测例都要求输出最少删除的点数。
题目链接
注释代码:
/* * Problem ID : POJ 3921 Destroying the bus stations * Author : Lirx.t.Una * Language : C++ * Run Time : 110 ms * Run Memory : 152 KB */ #include <memory.h>#include <stdio.h>#defineTRUE1#defineFALSE0//maximum number of bus stations//公交站的最大数量#defineMAXSTAN51//maximum number of roads//公交站之间通路的最大数量#defineMAXRODN4001typedefcharBOOL;//图的邻接表shorthd[MAXSTAN];//headshortac[MAXRODN];//arcshortnx[MAXRODN];//nextshorte;//edge//BFS广搜出一条从1到n的最短路径//由于每条边长都是1//所以没有必要Dij或者SPFA//广搜到的第一条通路即为1到n的最短路径charq[MAXSTAN];//queueBOOLvist[MAXSTAN];//visitedBOOLdl[MAXSTAN];//deleted,dl[i]用于判断i点是否被删除charovl[MAXSTAN];//overlap,表示i点的重叠层数,用于剪枝charprv[MAXSTAN][MAXSTAN];//用于记录BFS搜索出的最短路径//prv[depth][i]表示在第depth层中BFS搜出的路径中i点的前驱结点编号charbotm;//迭代深搜的界限bottomintn, m, k;voidaddarc( int u, int v ) {nx[e] = hd[u];ac[e] = v;hd[u] = e++;}intlen(char *prv) {//计算找出的路径的长度intu;//临时变量,指向一个点intcnt;//计数变量,记录路径长度cnt = 0;u = n;while ( u != 1 ) {u = prv[u];cnt++;}return cnt;}BOOLbfs(char *prv) {//寻找一条最短路径intfront, tail;intu, v;inti;memset(vist, 0, sizeof(vist));vist[1] = TRUE;q[0] = 1;front = 0;tail = 1;while ( front < tail ) {u = q[front++];for ( i = hd[u]; i; i = nx[i] )if ( !vist[ v = ac[i] ] && !dl[v] ) {//注意!!//还要看一下该店是否在dfs中删除了!!!prv[v] = u;if ( v == n )goto s;vist[v] = TRUE;q[tail++] = v;}}return TRUE;//表示1到n不可达,即1到n的距离无穷大,因此一定大于k,所以成功退出s:if ( len(prv) > k )//如果最短路径存在,计算其长度是否满足题中大于k的要求return TRUE;return FALSE;}BOOLdfs(int dp) {//迭代深搜,DFSID//depth,表示迭代的深度//这里就表示当前要删掉第几个点(第dp个点)if ( dp > botm )//超出界限则失败退出return FALSE;if ( bfs( prv[dp] ) )//如果在当前深度中存在>k的最短路径则成功退出return TRUE;intu;//临时变量,指向点的指针for ( u = prv[dp][n]; u != 1; u = prv[dp][u] ) {//遍历枚举当前层次中//最短路径中的每个点//枚举的顺序是从n到1if ( !ovl[u] ) {//!!!重要的剪枝//如果u在上面几层中被试探过了//就不必删除,可以直接忽略//即如果有原图中有部分路径相互重叠,如果上层搜索过重叠部分,则下层可以不必检验//可以使算法大大加速//具体证明不详!dl[u] = TRUE;//先删掉if ( dfs( dp + 1 ) )//然后在下一层中找一条最短路径检验是否合格return TRUE;dl[u] = FALSE;//检验完后再枚举上一个点,将u点还原!}ovl[u]++;//将u的重叠值+1}for ( u = prv[dp][n]; u != 1; u = prv[dp][u] )ovl[u]--;//当一层搜索完了就将所有重叠值-1,表示退出这1层,回溯到上层//使上层的ovl值保持为原样return FALSE;//没有搜出想要的结果,因此失败退出回溯到上层}intmain() {intu, v;while ( scanf("%d%d%d", &n, &m, &k), n ) {memset(hd, 0, sizeof(hd));e = 1;while ( m-- ) {scanf("%d%d", &u, &v);addarc( u, v );}for ( botm = 0; botm <= n - 2; botm++ ) {//表示先删0个点,再试一试只删1个点,再试只删2个点...//1和n不能删//第一次碰到的可行的结果就是最终答案//将删点信息和重叠信息初始化(清空)memset(dl, 0, sizeof(dl));memset(ovl, 0, sizeof(ovl));if ( dfs(0) ) {//从0个点删到botm个点为止printf("%d\n", botm);break;}}}return 0;}
无注释代码:
#include <memory.h>#include <stdio.h>#defineTRUE1#defineFALSE0#defineMAXSTAN51#defineMAXRODN4001typedefcharBOOL;shorthd[MAXSTAN];shortac[MAXRODN];shortnx[MAXRODN];shorte;charq[MAXSTAN];BOOLvist[MAXSTAN];BOOLdl[MAXSTAN];charovl[MAXSTAN];charprv[MAXSTAN][MAXSTAN];charbotm;intn, m, k;voidaddarc( int u, int v ) {nx[e] = hd[u];ac[e] = v;hd[u] = e++;}intlen(char *prv) {intu;intcnt;cnt = 0;u = n;while ( u != 1 ) {u = prv[u];cnt++;}return cnt;}BOOLbfs(char *prv) {intfront, tail;intu, v;inti;memset(vist, 0, sizeof(vist));vist[1] = TRUE;q[0] = 1;front = 0;tail = 1;while ( front < tail ) {u = q[front++];for ( i = hd[u]; i; i = nx[i] )if ( !vist[ v = ac[i] ] && !dl[v] ) {prv[v] = u;if ( v == n )goto s;vist[v] = TRUE;q[tail++] = v;}}return TRUE;s:if ( len(prv) > k )return TRUE;return FALSE;}BOOLdfs(int dp) {if ( dp > botm )return FALSE;if ( bfs( prv[dp] ) )return TRUE;intu;for ( u = prv[dp][n]; u != 1; u = prv[dp][u] ) {if ( !ovl[u] ) {dl[u] = TRUE;if ( dfs( dp + 1 ) )return TRUE;dl[u] = FALSE;}ovl[u]++;}for ( u = prv[dp][n]; u != 1; u = prv[dp][u] )ovl[u]--;return FALSE;}intmain() {intu, v;while ( scanf("%d%d%d", &n, &m, &k), n ) {memset(hd, 0, sizeof(hd));e = 1;while ( m-- ) {scanf("%d%d", &u, &v);addarc( u, v );}for ( botm = 0; botm <= n - 2; botm++ ) {memset(dl, 0, sizeof(dl));memset(ovl, 0, sizeof(ovl));if ( dfs(0) ) {printf("%d\n", botm);break;}}}return 0;}
单词解释:
barrack:n, 营房,兵营
military:adj, 军事的,军用的
vehicle:n, 车辆
ban:vt, 禁止
mission:n, 使命,任务
spy:n, 间谍
0 0
- POJ 3921 Destroying the bus stations
- POJ-3921-Destroying the bus stations
- POJ 3921 Destroying the bus stations
- POJ 3921 Destroying the bus stations 迭代加深搜索
- POJ 3921 Destroying the bus stations 迭代加深搜索
- POJ 3921 Destroying the bus stations 最大流
- Poj 3921 Destroying the bus stations【最小费用流】
- POJ 3921 Destroying the bus stations 已被翻译
- POJ--3921[Destroying the bus stations] 最小费用流+拆点
- POJ 3921 HDU 2485 Destroying the bus stations 最小费用最大流
- poj 3921/hdu 2485 Destroying the bus stations(最短路而非网络流费用流)
- POJ 3921 - Destroying the bus stations 构图最小费用最大流..
- poj 3921 Destroying the bus stations(最小割,点连通+floyd)
- POJ3921/HDU2485 Destroying the bus stations
- HDU2485(Destroying the bus stations)BFS+DFS
- Destroying the bus stations (dfs+bfs)
- HDU 2485 Destroying the bus stations
- hdu 2485 Destroying the bus stations
- Redhat/CentOS6.2 x86系统KVM虚拟机网络配置(二)—Bridge方式
- MyEclipse自动补全与快捷键设置
- select * from tablename where 1=0的意义
- 将博客搬至CSDN
- 集合框架
- POJ 3921 Destroying the bus stations
- 用strncat代替危险的strcat吧!(有空了再写, 各位亲)
- “海纳百川”下载器的使用方法
- 你最深爱的编程语言其实很烂
- Linux环境编程之文件I/O(三):文件的读写
- MPI学习-点对点通信
- C++中&的应用
- jdk1.5新特性
- OCP-1Z0-051 第123题 JOIN中的USING子句,ON子句