将树反向存储。从终点向起点反向搜索,。结果发现程序死循环。 从样例2得知: 还有可能向父亲节点走。
调整思路: 宽度搜索求最大路径,。
网上说:LCA。感觉有道理。如果用宽度搜索,这棵树就与无向图无异了。
还没有通过。 明天继续
#include <bits/stdc++.h>
#define debug
using namespace std;
const int MM=300000;
int n,m; //n:节点数 也是观察员数 m:玩家
struct Edge{
int father;
vector<int> sons;
int watch_time;
int count_ans;
};
Edge Tree[MM];
pair<int ,int> player[MM];
vector< pair<int ,int> > euler;
int index[MM];
void dfs(int root,int deep){
cout << root <<" "<< deep <<" "<< endl;
euler.push_back( make_pair(root, deep) );
for( int i=0; i < Tree[root].sons.size(); i++){
if( Tree[root].sons[i] !=0 )
dfs( Tree[root].sons[i], deep+1 );
}
euler.push_back( make_pair( root ,deep ));
}
int LCA(int s, int t){
dfs(1,0);
#ifdef debug
for(int i=0;i<euler.size();i++){
cout << i << " "<< euler[i].first << " "<< euler[i].second<< " "<<endl;
}
#endif
for(int i=0;i<euler.size();i++){
index[ euler[i].first ] = i; //这个节点在第i位置被访问。
}
int ans=100000;
for( int i = index[s] ;i<= index[t] ;i++ ){
ans = min( ans, euler[i].second );
}
return ans;
}
void solve(){
for(int i=1;i<=m;i++){
int lca = LCA( player[i].first, player[i].second );
//没注意到 样例中 2 到根以后,还要向下。。。
int s= player[i].first;
int t = player[i].second;
int time=0;
while(s!=lca){
s = Tree[s].father;
time++;
if( Tree[s].watch_time==time) Tree[s].count_ans++;
#ifdef debug
cout << "Tree[s].watch_time" << Tree[s].watch_time<< " ";
cout << "time" <<time <<" " ;
cout <<" Tree[s].count_ans " << Tree[s].count_ans << " ";
cout << endl;
#endif
}
if( Tree[lca].watch_time==time++) Tree[lca].count_ans++;
stack<int> tmp;
while(t!=lca){
tmp.push(t);
t=Tree[s].father;
}
while(!tmp.empty()){
int f=tmp.top();
tmp.pop();
if( Tree[f].watch_time==time++) Tree[f].count_ans++;
#ifdef debug
cout << "Tree[f].watch_time" << Tree[f].watch_time<< " ";
cout << "time" <<time <<" " ;
cout <<" Tree[f].count_ans " << Tree[f].count_ans << " ";
cout << endl;
#endif
}
}
}
int main()
{
cin>>n>>m;
for(int i=1; i<=n-1; i++){
int a,b;
cin >> a >> b;
Tree[b].father = a;
Tree[a].sons.push_back( b );
}
for(int i=1 ;i<=n; i++){
cin >> Tree[i].watch_time;
}
for(int i=1;i<=m;i++){
cin >> player[i].first;
cin >> player[i].second;
}
solve();
for(int i=1 ;i<=n; i++){
cout << Tree[i].count_ans<<endl;
}
return 0;
}
这个大佬的博客,写得挺好:
http://blog.csdn.net/herano/article/details/56687381