hdu4916 Count on the path

调了好久。。。。

•把树视为以1为根的有向树,然后将1删除

•原树变为一个森林,并且任一棵树的根节点均为原树中1的子节点

•只需要考虑最小编号前3小的三棵树

•记f[x][y]为去掉x和y两棵树后的最小值

•记dui[u]为u节点所在的树的根节点

•记dp[u]为在dui[u]这颗树中,不在路径<dui[u], u>上的节点编号最小值

•对于经过根节点的询问<u, v>

•ans<u, v> = min(dp[u], dp[v], f[bel[u]][bel[v]])

•维护g[x][0]和g[x][1],分别表示以x的子节点为根的子树中,编号最小值和次小值

•记F[x]为删除<bel[x], x>这条路径及x的子树,编号的最小值

•dp[u] = min(F[u], g[u][0])

•时间复杂度O(N),空间复杂度O(N)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<string>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<algorithm>
  8 #define re(i,l,r) for(int i=(l);i<=(r);i++)
  9 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 10 using namespace std;
 11 const int xxx=1000010;
 12 int n,m,head[xxx],Next[xxx<<1],zhi[xxx<<1],fa[xxx],ed;
 13 int g[xxx][2],f[4][4],dui[xxx],F[xxx],dp[xxx],xiao[3];
 14 void add(int a,int b)
 15 {
 16     Next[++ed]=head[a],head[a]=ed,zhi[ed]=b;
 17     Next[++ed]=head[b],head[b]=ed,zhi[ed]=a;
 18 }
 19 const int L=1e7;
 20 char in[L],*In,*End;
 21 char getc(){
 22     if(In==End){
 23         End=in+fread(in,1,L,stdin);
 24         if(in==End) return 0;
 25         In=in;
 26     }
 27     return *In++;
 28 }
 29 int inin(int &x){
 30     static char c;
 31     for(;c=getc(),!isdigit(c) && c;);
 32     if(!c) return 0;
 33     for(x=0;isdigit(c);c=getc()) (x*=10)+=c-‘0‘;
 34     return 1;
 35 }
 36 void dfs(int x)
 37 {
 38     g[x][0]=2147483647;g[x][1]=2147483647;
 39     for(int i=head[x];i;i=Next[i])if(zhi[i]!=fa[x])
 40     {
 41         fa[zhi[i]]=x;
 42         dfs(zhi[i]);
 43         int temp=min(g[zhi[i]][0],zhi[i]);
 44         if(temp<=g[x][0])
 45             g[x][1]=g[x][0],
 46             g[x][0]=temp;
 47         else g[x][1]=min(g[x][1],temp);
 48 //        else g[x][1]=min(g[x][1],g[zhi[i]][0]);
 49     }
 50 }
 51 void dfsxxx(int x,int t)
 52 {
 53     dui[x]=t;
 54     for(int i=head[x];i;i=Next[i])if(zhi[i]!=fa[x])
 55         dfsxxx(zhi[i],t);
 56 }
 57 void dfs2(int x)
 58 {
 59     if(x>1&&fa[x]!=1)
 60         if(g[fa[x]][0]==min(g[x][0],x))
 61             F[x]=min(F[fa[x]],g[fa[x]][1]);
 62         else F[x]=min(F[fa[x]],g[fa[x]][0]);else ;
 63     if(fa[x]==1)F[x]=2147483647;
 64     dp[x]=min(F[x],g[x][0]);
 65     for(int i=head[x];i;i=Next[i])if(zhi[i]!=fa[x])
 66         dfs2(zhi[i]);
 67 }
 68 //void dfs3(int x)
 69 //{
 70 //    for(int i=head[x];i;i=Next[i])if(zhi[i]!=fa[x])
 71 //        dfs3(zhi[i]);
 72 //}
 73 int hhh(int x)
 74 {
 75     x=dui[x];
 76     if(min(x,g[x][0])==xiao[0])return 0;
 77     else if(min(x,g[x][0])==xiao[1])return 1;
 78     else if(min(x,g[x][0])==xiao[2])return 2;
 79     else return 3;
 80 }
 81 int pre=0;
 82 int main()
 83 {
 84     freopen("in.in","r",stdin);
 85     freopen("out.out","w",stdout);
 86     while(inin(n))
 87     {
 88         inin(m);
 89         pre=0;
 90         memset(head,0,sizeof(head));ed=0;
 91         re(i,2,n)
 92         {
 93             int a,b;
 94 //            scanf("%d%d",&a,&b);
 95             inin(a),inin(b);
 96             add(a,b);
 97         }
 98         dfs(1);
 99         xiao[0]=xiao[1]=xiao[2]=n+1;
100         for(int i=head[1];i;i=Next[i])
101         {
102             dfsxxx(zhi[i],zhi[i]);
103             int temp=min(g[zhi[i]][0],zhi[i]);
104             if(xiao[0]>temp)
105                 xiao[2]=xiao[1],
106                 xiao[1]=xiao[0],
107                 xiao[0]=temp;
108             else if(xiao[1]>temp)
109                 xiao[2]=xiao[1],
110                 xiao[1]=temp;
111             else if(xiao[2]>temp)
112                 xiao[2]=temp;
113         }
114         f[3][3]=xiao[0];
115         f[3][0]=f[0][3]=xiao[1],f[3][1]=f[1][3]=xiao[0],f[3][2]=f[2][3]=xiao[0];
116         f[0][1]=f[1][0]=xiao[2],f[1][2]=f[2][1]=xiao[0],f[0][2]=f[2][0]=xiao[1];
117         dfs2(1);
118 //        dfs3(1);
119         dui[1]=-1;
120         re(i,1,m)
121         {
122             int a,b;
123 //            scanf("%d%d",&a,&b);
124             inin(a),inin(b);
125             a=a^pre,b=b^pre;
126             if(a==0)a++;if(b==0)b++;if(a>n)a=a%n+1;if(b>n)b=b%n+1;
127 //            printf("%d %d %d\n",a,b,pre);
128             if(dui[a]==dui[b]&&dui[a]!=-1){pre=1;}
129             else if(a==1)
130                     if(b==1){pre=xiao[0];}
131                     else
132                     {
133                         int now=hhh(b);
134                         re(i,0,2)if(i!=now){pre=min(dp[b],xiao[i]);break;}
135                     }
136                 else if(b==1)
137                 {
138                     int now=hhh(a);
139                     re(i,0,2)if(i!=now){pre=min(dp[a],xiao[i]);break;}
140                 }
141                 else {pre=min(min(dp[a],dp[b]),f[hhh(a)][hhh(b)]);}
142             printf("%d\n",pre);
143         }
144     }
145     return 0;
146 }
时间: 2024-10-24 05:20:16

hdu4916 Count on the path的相关文章

HDU4916 Count on the path(树dp??)

这道题的题意其实有点略晦涩,定义f(a,b)为 minimum of vertices not on the path between vertices a and b. 其实它加一个minimum index of vertices应该会好理解一点吧.看了一下题解,还有程序,才理清思路. 首先比较直接的是如果两点的路径没有经过根节点1的话,那么答案就直接是1,否则的话就必然有从根节点出发的两条路径,题解里说的预处理出f[u]表示不在根节点到u的路径上的点的最小值,然后取f[u]和f[v]的最小

HDU 4916 Count on the path

题意: 给定一棵树和m个询问  每个询问要求回答不在u和v两节点所形成的路径上的点的最小标号 思路: 一开始以为是LCA-  不过T了好几次-  后来发现不用LCA也可做 考虑每个询问u和v  如果他们的lca不是1  则1一定是答案  不过求lca会T  那么我们只需要在遍历树的时候给节点染色  染的颜色就是1的儿子的颜色  如果x这个点在y的子树中(y是1的儿子)那么他的颜色就是y 染完色后我们考虑答案是如何构成的 如图所示  答案即是  红色  蓝色  绿色的子树中节点的最小值  那么我们

Count on the path

Count on the path Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n. Let f(a,b) be the minimum of vertices not on the path bet

【树形DP】 HDU 4916 Count on the path

通道 题意:一棵树,求不经过路径的最小标号 代码: #include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; #define maxn 1005000 #define inf 0x

wc.exe命令行程序——c语言实现

1 /* 2 * 没能实现的功能:wc.exe -s递归处理目录下符合条件的文件 3 * wc.exe -x 显示图形界面 4 * 5 * 6 * 实现的功能: wc.exe -c显示文件的字符数. 7 * wc.exe -l行数. 8 * wc.exe -w单词. 9 * wc.exe -a空行数.代码行数.注释行数的统计测试 10 *` 11 * 12 */ 13 14 #include"iostream" 15 using namespace std; 16 void CharC

四则运算封装

form1 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace 四则运算 { public partial class Form1

ArcGIS API for Silverlight 调用GP服务加载等值线图层

原文:ArcGIS API for Silverlight 调用GP服务加载等值线图层 第二篇.Silverlight客户端调用GP服务 利用ArcGIS API for Silverlight实现GP服务调用,这里的雨量数据是通过一个WebService获取而来,主要信息是雨量站点的经纬度坐标值和某个时间段内的降雨量值三个主要字段. 以下是核心代码部分: <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/pr

AFNetworking2.0源码解析&lt;三&gt;

本篇说说安全相关的AFSecurityPolicy模块,AFSecurityPolicy用于验证HTTPS请求的证书,先来看看HTTPS的原理和证书相关的几个问题. HTTPS HTTPS连接建立过程大致是,客户端和服务端建立一个连接,服务端返回一个证书,客户端里存有各个受信任的证书机构根证书,用这些根证书对服务端 返回的证书进行验证,经验证如果证书是可信任的,就生成一个pre-master  secret,用这个证书的公钥加密后发送给服务端,服务端用私钥解密后得到pre-master secr

批量修改文件名

using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; name