HDU 4912 Paths on the tree (LCA+贪心)
来源:互联网 发布:c语言常用代码 编辑:程序博客网 时间:2024/04/29 21:09
题目大意:给出一棵树和一些点对,要求出最多可以同时有多少点对同时存在并且路径不重复覆盖。
用tanjan的LCA求出所有点对的最近公共祖先,再按照最近公共祖先在树上的深度排序,优先选择LCA深度深的点对,然后将LCA所在的子树标记,以后不能再选。
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn=200000+10;//树的点的两倍;struct edge{ int u,v,c,next;}e[maxn];struct Q{ int u,v,next; int lca,no;}que[maxn];int head[maxn],cnt;int head_que[maxn],cnt_que;int n,m;int father[maxn];bool vis[maxn];//int dist[maxn];int deep[maxn];int fa[maxn];int flag[maxn],num;void add(int u,int v){ e[cnt].u=u; e[cnt].v=v; e[cnt].next=head[u]; head[u]=cnt++;}void add_que(int u,int v){ que[cnt_que].u=u; que[cnt_que].v=v; que[cnt_que].next=head_que[u]; head_que[u]=cnt_que++;}void readtree(int n){ int u,v,c; for (int i=1;i<n;i++) { // scanf("%d%d%d",&u,&v,&c); scanf("%d%d",&u,&v); //add(u,v,c); // add(v,u,c); add(u,v); add(v,u); }}void readque(int m){ int u,v; for (int i=0;i<m;i++) { scanf("%d%d",&u,&v); if (flag[u]<flag[v]) { add_que(v,u); } else add_que(u,v); que[i].no=i; }}void init(){ memset(head,-1,sizeof(head)); cnt=0; memset(head_que,-1,sizeof(head_que)); cnt_que=0;}int find(int p)//并查集{ return p==father[p]?p:father[p]=find(father[p]);}void dfs(int p,int fa){ father[p]=p; for (int i=head[p];i!=-1;i=e[i].next) if (e[i].v!=fa) { dfs(e[i].v,p); father[e[i].v]=p; } vis[p]=1; for (int i=head_que[p];i!=-1;i=que[i].next) if (vis[que[i].v]) que[i].lca=find(que[i].v);}void LCA(int root){ memset(vis,0,sizeof(vis)); memset(father,0,sizeof(father));//并查集用 dfs(root,root);}bool cmp(Q a ,Q b){ return deep[a.lca]>deep[b.lca];}void dfs_flag(int p,int fa){//cout<<"P="<<p<<endl; for (int i=head[p];i!=-1;i=e[i].next) if (e[i].v!=fa) { dfs_flag(e[i].v,p); // cout<<"P="<<p<<endl; } flag[p]=num++;}//void dfs_dist(int p,int fa)//{// for (int i=head[p];i!=-1;i=e[i].next)// if (e[i].v!=fa)// {// dist[e[i].v]=dist[p]+e[i].c;// dfs_dist(e[i].v,p);// }//}void dfs_deep(int p){ for (int i=head[p];i!=-1;i=e[i].next) if (e[i].v!=fa[p]) { fa[e[i].v]=p; deep[e[i].v]=deep[p]+1; dfs_deep(e[i].v); }}void dfs_vis(int p){ vis[p]=1; for (int i=head[p];i!=-1;i=e[i].next) if (e[i].v!=fa[p]&&!vis[e[i].v]) { dfs_vis(e[i].v); }}int main(){ freopen("in.txt","r",stdin); int T; //scanf("%d",&T); // cout<<T<<endl; //while (T--) while (~scanf("%d%d",&n,&m)) { //cout<<T<<endl; int root=1; init(); // scanf("%d%d",&n,&m); readtree(n);//读入n个点的树; // cnt=0; num=0; dfs_flag(root,-1);//对树按照左右根标号; readque(m);//读入m个询问; LCA(1);//LCA deep[root]=1; fa[root]=root; dfs_deep(root); sort(que,que+m,cmp); // dist[root]=0; // dfs_dist(root,-1); int ans=0; memset(vis,0,sizeof(vis)); for (int i=0;i<m;i++) if (!vis[que[i].u]&&!vis[que[i].v]) { dfs_vis(que[i].lca); ans++; } cout<<ans<<endl;// for (int i=0;i<m;i++)// cout<<dist[que[i].u]+dist[que[i].v]-2*dist[que[i].lca]<<endl; } return 0;}
0 0
- HDU 4912 - Paths on the tree (LCA 贪心)
- HDU 4912 Paths on the tree (LCA+贪心)
- HDU 4912 Paths on the tree(LCA+贪心)
- HDU 4912 Paths on the tree LCA 排序贪心
- hdu 4912 Paths on the tree(lca+贪心)
- hdu 4912 Paths on the tree lca+贪心
- hdu 4912 Paths on the tree LCA + 贪心
- hdu 4912 Paths on the tree (LCA+贪心)
- HDU 4912 Paths on the tree 贪心+lca
- 【HDU】4912 Paths on the tree 离线LCA+贪心
- hdu 4912Paths on the tree (LCA)
- hdu4912 Paths on the tree --- LCA贪心
- HDU4912 Paths on the tree(数据结构,lca,贪心)
- hdu 4912 Paths on the tree(树链剖分+贪心)
- HDU 4912(Paths on the tree-树上取链,贪心)
- HDU 4912 Paths on the tree
- hdu 4912 Paths on the tree
- HDU-4912-Paths on the tree
- [编程之美] PSet3.1 字符串移位包含的问题
- Java线程(六):线程池
- SQL SERVER SQLOS的任务调度
- c++迭代器
- 一个简单的加密(java语言实现)
- HDU 4912 Paths on the tree (LCA+贪心)
- 【BJOI 2014】总结
- java 局部内部类
- java实现k-means算法
- hdu1196
- Unity3D导入外部任务模型无法触发鼠标事件解决方案
- POJ-1611-The Suspects(并查集)
- 窗体的复用----窗体继承
- POJ 3086 Triangular Sums