美团CODEM 最长树链 枚举质因数,DFS或者直接BFS
来源:互联网 发布:java 生成汉字验证码 编辑:程序博客网 时间:2024/06/06 01:45
题意:树链是指树里的一条路径。美团外卖的形象代言人袋鼠先生最近在研究一个特殊的最长树链问题。现在树中的每个点都有一个正整数值,他想在树中找出最长的树链,使得这条树链上所有对应点的值的最大公约数大于1。请求出这条树链的长度。
解法:枚举每个约数,保留对应的边,做一次最长路径。因为一个数的约数个数可以保证,所以复杂度符合要求。
下面是官方题解给的代码:
#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <cmath>#include <iostream>#include <algorithm>#include <map>#include <vector>using namespace std;int n, l, c[100001], len, value[100001], visit[100001], V[100001];bool b[100001];map< int, vector<int> > factor;struct node{ node *next; int where;} a[200001], *first[100001];inline void makelist(int x, int y) { a[++l].where = y; a[l].next = first[x]; first[x] = &a[l];}pair<int, int> bfs(int init, int v, int round) { c[1] = init; visit[init] = 1; int pos = 0, will = 0; int k = 1, l = 1; for (; l <= k; ++l) { int m = c[l]; if (visit[m] > will) will = visit[m], pos = m; for (node *x = first[m]; x; x = x->next) if (!(value[x->where] % v) && !visit[x->where]) { visit[x->where] = visit[m] + 1; c[++k] = x->where; } } if (round == 0) for (int i = 1; i <= k; i++) visit[c[i]] = 0; return make_pair(pos, will);}int calc(int v) { vector<int> idx = factor[v]; int will = 0; for (int i = 0; i < idx.size(); i++) if (!visit[idx[i]]) { will = max(will, bfs(bfs(idx[i], v, 0).first, v, 1).second); } for (int i = 0; i < idx.size(); i++) visit[idx[i]] = 0; return will;}int main() { len = 0; memset(b, false, sizeof(b)); for (int i = 2; i <= 100000; i++) { if (!b[i]) c[++len] = i; for (int j = 1; j <= len; ++j) if (c[j] * i > 100000) break; else { b[c[j] * i] = true; if (!(i % c[j])) break; } } scanf("%d", &n); memset(first, 0, sizeof(first)); l = 0; for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); makelist(x, y); makelist(y, x); } factor.clear(); for (int i = 1; i <= n; i++) { int x; scanf("%d", &x); value[i] = x; for (int j = 1; c[j] * c[j] <= x; ++j) if (!(x % c[j])) { if (factor.find(c[j]) == factor.end()) factor[c[j]].clear(); factor[c[j]].push_back(i); for (; !(x % c[j]); ) x /= c[j]; } if (x != 1) { if (factor.find(x) == factor.end()) factor[x].clear(); factor[x].push_back(i); } } int ans = 0; memset(visit, 0, sizeof(visit)); memset(V, 0, sizeof(V)); for (map< int, vector<int> >::iterator itr = factor.begin(); itr != factor.end(); ++itr) ans = max(ans, calc(itr->first)); printf("%d\n", ans);}
然后还看到了一种直接BFS爆搜莽过去的,能过简直玄学。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream>#include <iostream> #include <cmath> #include<cstdio> #include<cstring> #include <algorithm>#include <cctype>#include <utility>#include <map>#include <string>#include <cstdlib>#include <queue>#include <numeric>#include <vector>#include<set>#include <cctype>using namespace std;const int maxn = 100050;int maxlen = 0;int rd[maxn];int a[maxn];vector<int>v[maxn];inline bool scan(int &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; //EOF while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1;}struct node { int x; int len; int gcd;};void bfs(int x, int len, int gcd){ node n1, n2; queue<node>q; n1.x = x; n1.len = len; n1.gcd = gcd; q.push(n1); while (!q.empty()) { node n1 = q.front(); q.pop(); int nx = n1.x; int nlen = n1.len; int ngcd = n1.gcd; maxlen = max(nlen, maxlen); for(int i=0;i<v[nx].size();i++) { int next = v[nx][i]; int usegcd = __gcd(a[next], ngcd); if (usegcd == 1) { n2.gcd = a[next]; n2.len = 1; n2.x = next; q.push(n2); } else { n2.gcd = usegcd; n2.len = 1+nlen; n2.x = next; q.push(n2); } } }}/*void dfs(int x, int len,int gcd){ maxlen = max(len, maxlen); for (int i = 0; i < v[x].size(); i++) { int next = v[x][i]; int usegcd = __gcd(a[next], gcd); if (usegcd ==1) dfs(next, 1, a[next]); else dfs(next, len+1, usegcd); }}*/int main(){ int n; scan(n); for (int i = 2; i <= n; i++) { int a, b; scan(a); scan(b); v[a].push_back(b); rd[b]++; } int go = 0; for (int i = 1; i <= n; i++) { if (rd[i] == 0) go = i; scan(a[i]); } bfs(go,1,a[go]); printf("%d", maxlen); return 0;}
阅读全文
0 0
- 美团CODEM 最长树链 枚举质因数,DFS或者直接BFS
- 美团CodeM 初赛 A伦 最长树链 xjb枚举+dfs
- [LOJ#6159][美团 CodeM 初赛 Round A][暴力即正解]最长树链
- 【loj6159】「美团 CodeM 初赛 Round A」最长树链
- 美团codeM预赛B 黑白树
- 美团codeM比赛
- 美团CODEM 字串
- 美团CODEM 数码
- CodeM资格赛 Round A 最长树链
- 美团codeM资格赛 优惠券
- 美团codeM资格赛 数码
- 美团codeM资格赛 锦标赛
- 美团CODEM 送外卖
- CodeM美团B轮A题 黑白树 【贪心】
- 美团CODEM 黑白树 思维,拓扑DP
- codeM 美团 b轮 A题 黑白树
- UVA10557SPFA或者bfs+dfs
- 美团CodeM 资格赛第一题
- 从零开始搭建一个完善的MVP开发框架(四) —对View(Activity,Fragment等)层组件进行封装简化View层的开发
- 学习OpenCV——行人检测&人脸检测(总算运行出来了)
- JSF入门
- 13.2. Copy Control and Resource Management
- jVM内存模型(二、重排序与同步)
- 美团CODEM 最长树链 枚举质因数,DFS或者直接BFS
- unity人物残影的实现
- HashMap简介
- 黑客-ubuntu下scapy的ARP攻击(1)
- python脚本作业
- 从零开始搭建一个完善的MVP开发框架(五),通过组件化开发优化项目的结构
- FlowLayout 点击子项无效的问题
- df命令
- 生產者消費者(解決綫程同步問題)