ZOJ Problem Set - 3172 Extend 7-day Vacation
Chieh
posted @ 2015年7月21日 16:06
in ZOJ
, 249 阅读
飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3204
题意:就是找两个点,使得路径上的点最多。
分析:刚看不知道从何下手,再仔细看看note就好了,note前半部分就是说图是连通的,因为说点是直接或则间接相连的,后半部分说明图没有环,因为说如果出去之后要回原来的点,必须经过一条至少两次。有这个的话就可以知道给的图是颗树,然后求树上两点之间的点数最多,即距离最大。那么可以用树形DP,假设当前的点为k,它的子树最大的深度为i和j,那么就可以知道当前的路径为i和j之间的和再加1(k这个点),然后更新MAX,然后把k和最大的子树路径递归上去,用来更新k的父节点就可以了,然后最后要判断MAX是否大于7,最后啪啪啪就可以AC了
/* Author:Chieh Because Of Coding */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #include <stack> #define LL long long #define INF 1e9 #define EPS 1e-9 using namespace std; const int maxn=1234; vector<int> V[maxn]; int n,m; void init() { for(int i=1; i<=n; i++)V[i].clear(); int u,v; for(int i=1; i<n; i++) { scanf("%d%d",&u,&v); u++; v++; V[u].push_back(v); V[v].push_back(u); } } bool cmp(int a,int b) { return a>b; } int MAX; int DFS(int now,int fa) { vector<int> need; need.push_back(0); need.push_back(0); for(int i=0; i<V[now].size(); i++) { int u=V[now][i]; if(u==fa)continue; int p=DFS(u,now); need.push_back(p); } sort(need.begin(),need.end(),cmp); MAX=max(MAX,need[0]+need[1]+1); return need[0]+1; } void play() { MAX=0; DFS(1,-1); if(MAX<7)printf("Impossible\n"); else printf("%d\n",MAX); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { init(); play(); } // cout << "Hello world!" << endl; return 0; }