• 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
    ",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
    ",pre);
    143         }
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    使用事务和SqlBulkCopy导入大批量数据
    Windows Server中禁止Administrator用户登录远程桌面
    SQL和C#的常用时间日期处理
    转:SQL Server数据库查询速度慢的原因
    火把节之夜,想发飙
    判断一个字符串是否为空
    .net中的using批注
    [转帖]删除鼠标右键的“用阿里旺旺打开此文件”的命令
    近凌晨12点却毫无睡意
    SQL SERVER取得汉字的拼音缩写
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5345642.html
Copyright © 2020-2023  润新知