HOJ 1030 Labyrinth----------------两次BFS求树的直径(图的最长路)
2013-01-30 00:01
369 查看
Labyrinth
2.如果是有向图的话,可以按照拓扑序列dp,时间复杂度也是o(V+E)(广搜的复杂度)。
//题意:求树的直径 //思路: // 树的直径是指树的最长简单路。求法: 两遍BFS :先任选一个起点BFS找到最长路的终点,再从终点进行BFS,则第二次BFS找到的最长路即为树的直径; // 原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点 // 证明: 1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾) // 2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了 // 所以v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度 //hint:。。。。。 #include<iostream> #include<cstring> #include<cstdio> #include<queue> #define maxlen 1010 struct node { int x,y,step; }; char mat[maxlen][maxlen]; int mat2[maxlen][maxlen],maxt; int dir[4][2]= {{-1,0},{1,0},{0,-1},{0,1}}; using namespace std; node BFS1(node s,int a,int b)//任意一个点找到直径的另一点(以这个点为起点的最长路的终点) { queue<node> q; node ol,ne,ans; while(!q.empty()) q.pop(); maxt=-1;//当前最大步子记录 s.step=0; mat[s.x][s.y]='#'; q.push(s); while(!q.empty()) { ol=q.front(); q.pop(); if(ol.step>maxt) { maxt=ol.step; ans=ol; }//出队就要判断 for(int l=0; l<4; l++) { ne.x=ol.x+dir[l][0]; ne.y=ol.y+dir[l][1]; ne.step=ol.step; if(ne.x>a||ne.y>b||ne.x<0||ne.y<0||mat[ne.x][ne.y]=='#')continue; else { mat[ne.x][ne.y]='#'; ne.step++; if(ne.step>maxt) { maxt=ne.step; ans=ne; }//更新之后要判断 q.push(ne); } } } return ans; } node BFS2(node s,int a,int b) { queue<node> q; node ol,ne,ans; while(!q.empty()) q.pop(); maxt=-1; s.step=0; mat2[s.x][s.y]=1; q.push(s); while(!q.empty()) { ol=q.front(); q.pop(); if(ol.step>maxt) { maxt=ol.step; ans=ol; } for(int l=0; l<4; l++) { ne.x=ol.x+dir[l][0]; ne.y=ol.y+dir[l][1]; ne.step=ol.step; if(ne.x>a||ne.y>b||ne.x<0||ne.y<0||mat2[ne.x][ne.y]==1)continue; else { mat2[ne.x][ne.y]=1; ne.step++; if(ne.step>maxt) { maxt=ne.step; ans=ne; } q.push(ne); } } } return ans; }//同BFS1 int main() { int n,a,b,i,j; node s; cin >> n; while(n--) { memset(mat,'0',sizeof(mat)); memset(mat2,0,sizeof(mat2)); cin >> b >> a; for(i=0;i<a;i++) for(j=0;j<b;j++) cin >> mat[i][j]; for(i=0; i<a; i++) for(j=0; j<b; j++) if(mat[i][j]=='#') mat2[i][j]=1; bool f=false; for(i=0; i<a; i++) { for(j=0; j<b; j++) { if(mat[i][j]=='.') { s.x=i; s.y=j; s.step=0; f=true;//用来跳出两层循环 break; } } if(f) break; } printf("Maximum rope length is %d.\n", BFS2(BFS1(s,a,b),a,b).step); } return 0; }
2.如果是有向图的话,可以按照拓扑序列dp,时间复杂度也是o(V+E)(广搜的复杂度)。
相关文章推荐
- POJ 1985 Cow Marathon(两次BFS求树的直径(最长路))
- HOJ 1030 && POJ 1383 - Labyrinth(树的直径、图的直径)
- POJ1383 Labyrinth(树的直径:两次BFS)
- hdu 4514 并查集判断无向图是否有环+树(无环连通图)的直径(两次bfs)
- Hoj 1030 Labyrinth
- 【hoj】1030 Labyrinth
- POJ 1383 Labyrinth (bfs 树的直径)
- URAL 1145. Rope in the Labyrinth(两次BFS啊 )
- CCF 201503-4 网络延时(树的直径,两次BFS)
- Light OJ 1094 - Farthest Nodes in a Tree【树的直径 两次bfs】
- ccf 201503-4 网络延时 树的直径问题(两次bfs)
- Poj 1383--Labyrinth【树的直径】【bfs】
- POJ 1383 Labyrinth(BFS 树的直径)
- POJ 1383 Labyrinth(两次bfs求最长路径)
- Hihocoder 1050 树中的最长路(树的直径 两次dfs/折点)
- #1050 : 树中的最长路(两次BFS)
- 两次BFS求树的直径(算法导论22.2-7)
- hihocoder#1050 : 树中的最长路(树中最长路算法 两次BFS找根节点求最长+BFS标记路径长度+bfs不容易超时,用dfs做TLE了)
- (简单)搜索 HOJ 1030 Labyrinth
- poj 1383 Labyrinth 【迷宫图 BFS实现 树的直径裸题】