ACdream 1728 SJY's First Task
简单题。
先建树,我用邻接表来存了。然后对于每个叶子结点DFS一下,DFS深度超过了K就return,找到了叶子节点就记录下来,最后排个序,然后输出答案。
由于结点编号比较奇葩,所以用两个map来转换一下。这个代码写的很丑,大半夜写的,迷迷糊糊。
#include<cstdio> #include<cstring> #include<cmath> #include<map> #include<string> #include<vector> #include<iostream> #include<algorithm> using namespace std; char s[1000]; map<int, int>zh; map<int, int>ff; vector<int>ljb[100000]; int flag[100000], rr[100000]; int ls, K, ye; int u[1000], k[105]; struct ANS { int A, B, C; }ans[10000 + 10]; int gh = 0; bool cmp(const ANS&a, const ANS&b) { if (a.A == b.A&&a.B == b.B) return a.C<b.C; if (a.A == b.A) return ff[a.B]<ff[b.B]; return ff[a.A]<ff[b.A]; } void DFS(int now, int b) { if (b>K) return; int i; if (flag[now] == 1 && now != ye) { ans[gh].A = ye; ans[gh].B = now; ans[gh].C = b; gh++; return; } for (i = 0; i<ljb[now].size(); i++) { if (rr[ljb[now][i]] == 0) { rr[ljb[now][i]] = 1; DFS(ljb[now][i], b + 1); } } } int main() { int n, i, j, o; while (~scanf("%d", &K)) { scanf("%d", &n); zh.clear(); ff.clear(); memset(flag, 0, sizeof(flag)); int p = 1, tot; gh = 0; zh[774388357] = p; ff[p] = 774388357; p++; for (i = 0; i<100000; i++) ljb[i].clear(); for (o = 0; o<n; o++) { scanf("%d %s", &k[o], s); ls = 0; if (zh[k[o]] == 0) zh[k[o]] = p, ff[p] = k[o], p++; flag[zh[k[o]]] = 1; int len = strlen(s); j = 0; tot = 0; for (i = 0; i <= len; i++) { if (s[i] == ',' || s[i] == '\0') { if (zh[ls] == 0) zh[ls] = p,ff[p] = ls,p++; u[tot] = zh[ls], tot++, ls = 0; } else ls = ls * 10 + s[i] - '0'; } ljb[1].push_back(u[0]); ljb[u[0]].push_back(1); for (i = 1; i<tot; i++) { ljb[u[i - 1]].push_back(u[i]); ljb[u[i]].push_back(u[i - 1]); } ljb[u[tot - 1]].push_back(zh[k[o]]); ljb[zh[k[o]]].push_back(u[tot - 1]); } for (i = 0; i<n; i++) { ye = zh[k[i]]; memset(rr, 0, sizeof(rr)); rr[ye] = 1; DFS(ye, 0); } sort(ans, ans + gh, cmp); for (i = 0; i<gh; i++) { cout << ff[ans[i].A]; cout << " "; cout << ff[ans[i].B]; cout << " "; cout << ans[i].C; cout << endl; } } return 0; }