标签:des style blog color java os io strong
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 531 Accepted Submission(s): 182
题目意思:
给出一棵树,总共n个结点n-1条边,然后给出m个条路径的两端结点的编号,求m条路径互相不相交的最大个数为多少。
思路:
求出每个路径两端端点的最近公共结点,然后把lca按照深度从大到小排序,然后开始贪心,每次若这条路径上的点没有被visited过,那么ans++,然后把这条路径上所有点visited。最终结果即为ans。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <queue> 6 #include <iostream> 7 using namespace std; 8 #define N 100005 9 #define M 20 10 11 int n, m; 12 13 struct Edge{ 14 int u, v, f, w; 15 Edge(int a=0,int b=0,int c=0,int d=0):u(a),v(b),f(c),w(d){} 16 }e[N]; 17 18 int dep[N]; 19 int f[N][M]; 20 int visited[N]; 21 vector<int>ve[N]; 22 23 void init(){ 24 memset(dep,0,sizeof(dep)); 25 memset(f,0,sizeof(f)); 26 memset(visited,0,sizeof(visited)); 27 for(int i=0;i<=n;i++) ve[i].clear(); 28 } 29 30 bool cmp(Edge a,Edge b){ //把路径按照最近公共祖先的深度从大到小排序 31 return a.w>b.w; 32 } 33 void bfs(int ss){ //bfs求深度dep[]和向上走的步数f[][](在线算法) 34 queue<int>Q; 35 dep[ss]=1; 36 f[ss][0]=1; 37 Q.push(ss); 38 int u, v, i; 39 while(!Q.empty()){ 40 u=Q.front(); 41 Q.pop(); 42 for(i=1;i<M;i++) f[u][i]=f[f[u][i-1]][i-1]; 43 for(i=0;i<ve[u].size();i++){ 44 v=ve[u][i]; 45 if(v!=f[u][0]){ 46 dep[v]=dep[u]+1; 47 f[v][0]=u; 48 Q.push(v); 49 } 50 } 51 } 52 } 53 54 void dfs(int u){ //dfs把最近公共祖先结点以下的点全部visited使得这条路径全部visited 55 int v, i; 56 visited[u]=1; 57 for(i=0;i<ve[u].size();i++){ 58 v=ve[u][i]; 59 if(dep[v]>dep[u]&&!visited[v]){ 60 dfs(v); 61 } 62 } 63 } 64 65 int lca(int x,int y){ //求x和y的最近公共祖先 66 if(dep[x]<dep[y]) swap(x,y); 67 int i, k; 68 k=dep[x]-dep[y]; 69 for(i=0;i<M;i++){ 70 if(1<<i&k) x=f[x][i]; 71 } 72 if(x==y) return x; 73 for(i=M-1;i>=0;i--){ 74 if(f[x][i]!=f[y][i]){ 75 x=f[x][i]; 76 y=f[y][i]; 77 } 78 } 79 return f[x][0]; 80 } 81 82 main() 83 { 84 int x, y; 85 int i, j, k, ans; 86 while(scanf("%d %d",&n,&m)==2){ 87 init(); 88 for(i=1;i<n;i++){ 89 scanf("%d %d",&x,&y); 90 ve[x].push_back(y); 91 ve[y].push_back(x); 92 } 93 bfs(1); 94 for(i=0;i<m;i++){ 95 scanf("%d %d",&x,&y); 96 int ff=lca(x,y); 97 // printf("%d\n",ff); 98 e[i]=Edge(x,y,ff,dep[ff]); 99 } 100 sort(e,e+m,cmp); 101 ans=0; 102 for(i=0;i<m;i++){ 103 if(!visited[e[i].u]&&!visited[e[i].v]){ //两个端点没有被visited那么整条路径也没被visited,想一想为什么 104 dfs(e[i].f); 105 ans++; 106 } 107 } 108 printf("%d\n",ans); 109 } 110 }
HDU 4912 LCA+贪心,布布扣,bubuko.com
标签:des style blog color java os io strong
原文地址:http://www.cnblogs.com/qq1012662902/p/3895784.html