ZOJ Problem Set - 2013 Labyrinth
Chieh
posted @ 2015年7月30日 14:38
in ZOJ
, 387 阅读
飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1013
题意:起先看的很迷糊啊。就是给你C*R的矩阵,然后矩阵里面是#(不可走)或.(可走),然后Input最后一句话每两个点之间最多正好就一条路,所以说路径不包含圈,所以是棵树,然后Output说输出两个点之间最长的长度是多少。
分析:知道题意的话就很简单了。可以用树形DP ,假设当前的节点为fa,如果它没有子节点,那么它就是叶子节点,那么直接返回1,如果它有一个子节点,那么最长就是子节点返回的值,用这个值更新最大值,然后返回最大值+1到fa的父节点,如果它有多余两个子节点。那么从它的子节点选择2个最大子节点,然后相加,更新最大值,再把最大值的一个子节点+1返回到fa的父节点,这样最后的最大值就是我们要求的最大路径了。啪啪啪就可以AC了。
/* Author:Chieh Because Of Coding */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <map> #include <stack> #include <queue> #define LL long long #define INF 1e9 #define EPS 1e-9 using namespace std; const int maxn=1234; bool ai[maxn][maxn]; int T; int n,m; char ch[maxn]; void init() { scanf("%d%d",&m,&n); memset(ai,0,sizeof(ai)); for(int i=1; i<=n; i++) { scanf("%s",ch+1); for(int j=1; j<=m; j++) { if(ch[j]=='.')ai[i][j]=1; } } } bool cmp(int a,int b) { return a>b; } bool vis[maxn][maxn]; int MAX; int c1[]= {1,0,-1,0}; int c2[]= {0,1,0,-1}; int DFS(int x,int y) { int l1=-1,l2=-1; for(int i=0; i<4; i++) { int nx=x+c1[i]; int ny=y+c2[i]; if(!ai[nx][ny])continue; if(vis[nx][ny])continue; vis[nx][ny]=1; int q=DFS(nx,ny); if(l1==-1){ l1=q; } else{ if(q>l1){ l2=l1; l1=q; } else if(q>l2){ l2=q; } } } if(l1==-1) { return 1; } if(l2==-1) { MAX=max(MAX,l1); return l1+1; } MAX=max(MAX,l1+l2); return l1+1; } void play() { MAX=0; memset(vis,0,sizeof(vis)); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(!vis[i][j]) { vis[i][j]=1; if(!ai[i][j])continue; DFS(i,j); } } } printf("Maximum rope length is %d.\n",MAX); } int main() { scanf("%d",&T); while(T--) { init(); play(); } //cout << "Hello world!" << endl; return 0; }