hdu5156 LCA
来源:互联网 发布:成都mac专柜价格多少 编辑:程序博客网 时间:2024/06/05 18:55
具体解法就是bc首页的解法了,排个颜色序和dfs序,然后按照解法一路解下去就行了。注意一定要pai排dfs序,不然会更新错误的公共祖先节点。
代码:
#include <iostream>#include <cstring>#include <cstdio>#include <queue>#include <stack>#include <map>#include <string>#include <algorithm>#define ll long long int#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define delf int m=(l+r)>>1using namespace std;int f[50005]; //当前集合的父节点为当前访问的子树公共祖先int mark[50005]; vector <int> m[50005];vector <int> q[50005];int ans[50005];int id[50005]; //dfs序int n,m1,cnt;struct color{ int v; int c;} c[500005];bool cmp(color a,color b){ if (a.c!=b.c) return a.c<b.c; return id[a.v]<id[b.v];}void init(){ for (int i=1;i<=n;i++) { m[i].clear(); q[i].clear(); } for (int i=1;i<=n;i++) ans[i]=0; for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=n;i++) mark[i]=0;}void dfs(int u,int t){ id[u]=cnt++; for (int i=0;i<m[u].size();i++) { if (m[u][i]==t) continue ; dfs(m[u][i],u); }}int find(int x){ if (f[x]==x) return x; return f[x]=find(f[x]);}int LCA(int u,int t){ for (int i=0;i<m[u].size();i++) { if (m[u][i]==t) continue ; int s=LCA(m[u][i],u); ans[u]+=s; f[m[u][i]]=u; } for (int i=0;i<q[u].size();i++) { if (mark[q[u][i]]==1) ans[find(q[u][i])]--; } mark[u]=1; return ans[u];}int scan() { //输入外挂 int res = 0, flag = 0; char ch; if((ch = getchar()) == '-') flag = 1; else if(ch >= '0' && ch <= '9') res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9') res = res * 10 + (ch - '0'); return flag ? -res : res;}void out(int a) { //输出外挂 if(a < 0) { putchar('-'); a = -a; } if(a >= 10) out(a / 10); putchar(a % 10 + '0');}int main(){ while (~scanf("%d%d",&n,&m1)) { init(); for (int i=1;i<n;i++) { int a,b; a=scan(); b=scan(); //scanf("%d%d",&a,&b); m[a].push_back(b); m[b].push_back(a); } for (int i=1;i<=m1;i++) { int a,b; a=scan(); b=scan(); //scanf("%d%d",&a,&b); c[i].v=a; c[i].c=b; } cnt=1; dfs(1,0); //获得每个节点dfs序位置 sort(c+1,c+m1+1,cmp); //按照颜色第一关键字,dfs序第二关键字排序,这样能保证颜色相同的节 //点在访问时是顺序的,否则会因为减1的节点位置不对而出错。 ans[c[1].v]++; for (int i=2;i<=m1;i++) { if (c[i].c==c[i-1].c&&c[i].v==c[i-1].v) continue ; ans[c[i].v]++; if (c[i].c==c[i-1].c) { q[c[i].v].push_back(c[i-1].v); q[c[i-1].v].push_back(c[i].v); } } int t=LCA(1,0); for (int i=1;i<n;i++) { out(ans[i]); putchar(' '); } //printf("%d ",ans[i]); printf("%d\n",ans[n]); }}
0 0
- hdu5156 LCA
- HDU5156(离线tarjan+打标记)
- LCA
- LCA
- lca
- LCA
- LCA
- lca
- LCA
- LCA
- LCA
- LCA
- LCA
- lca
- lca
- LCA
- lca
- LCA
- python 的 matplotlib画图 画曲线图
- 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取"产品付费数量等于0的问题"】
- Single Number
- Java 创建线程的两种方法
- json.parse() and json.stringify()
- hdu5156 LCA
- [cocos2d-js]cc.RenderTexture几种用法(数字图片、刮刮乐效果)
- HDOJ 最小公倍数(欧几里得算法求最大公约数)
- 实用Xcode改名
- makefile自动生成依赖
- 编辑器与编译器详解
- TFS(Team Foundation Server)介绍和入门
- bss段和common段的区别
- 高斯滤波器