SDNU 1057.樹的查詢
Time Limit: 1000 MS Memory Limit: 32768 KB
Total Submission(s): 350 Accepted Submission(s): 61
Description
給定 n(1 <= n <= 1000000), m(1 <= m <= 10) 分別表示一棵樹中節點的個數及查詢的數量,每個節點的編號爲給定的順序,之後給定每個節點的父節點編號,及 m 個查詢,每個查詢中,給定一個節點編號,對於每個查詢,按編號從小到大輸出該節點所有子節點。
Input
第一行兩個整數n, m,之後n行,每行兩個整數a, b,表示編號爲a的節點的父節點是b,b爲0表示沒有父節點,數據保證編號爲1至n的節點均在a位置出現一次,之後一行m個整數,表示每個查詢要查詢的節點編號。
Output
m行,每行若干個從小到大排好序的、用一個空格隔開的整數,表示該次查詢的節點的所有子節點。
Sample Input
5 1
1 0
4 1
2 1
5 1
3 1
1
Sample Output
2 3 4 5
Source
Unknown
解析一下吧,說實話這是一道很水的題目,前提是你看懂題目了…我一開始把子節點理解成子節點、子節點的子節點、子節點的子節點的子節點…事實證明我想多了,其實就這麼簡單,不用vector也可以,我用vector只是練練手,大家僅供參考。
附上ac代碼:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
using namespace std;
int c[1000005];
map<int,vector<int> > sh;
int main()
{
int n,m;
scanf("%d %d",&n,&m);
while(n--)
{
int a,b;
scanf("%d %d",&a,&b);
sh[b].push_back(a);
}
while(m--)
{
memset(c,0,sizeof(c));
int a;
scanf("%d",&a);
int j=0;
for(int i=0;i<sh[a].size();i++,j++)
{
c[j]=sh[a][i];
}
sort(c,c+j);
if(c[j-1]!=0)
{
for(int i=0; i<j-1; i++)
printf("%d ",c[i]);
cout<<c[j-1];
}
cout<<endl;
}
return 0;
}
那麼我們索性拓展一下,就以我一開始想錯的點出發,寫一道題,就是輸出子節點之下的所有節點,可以想一想,沒有題,附上我的代碼給大家參考一下(因爲沒有題,也不知道ac不。但至少我沒有找到錯誤。)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
using namespace std;
int c[1000005];
map<int,vector<int> > sh;
int main()
{
int n,m;
scanf("%d %d",&n,&m);
while(n--)
{
int a,b;
scanf("%d %d",&a,&b);
sh[b].push_back(a);
}
while(m--)
{
memset(c,0,sizeof(c));
int a;
scanf("%d",&a);
queue<int>js;
js.push(a);
int j=0;
while(!js.empty())
{
int b=js.front();
js.pop();
for(int i=0; i<sh[b].size(); i++)
{
c[j]=sh[b][i];
j++;
js.push(sh[b][i]);
}
}
sort(c,c+j);
if(c[j-1]!=0)
{
for(int i=0; i<j-1; i++)
printf("%d ",c[i]);
cout<<c[j-1]<<endl;
}
}
return 0;
}
唉,一直覺得自己英語不好,沒想到語文也不咋地,多看書啊!!!