zoukankan      html  css  js  c++  java
  • 【点分治】【哈希表】bzoj2599 [IOI2011]Race

    给nlog2n随便过的跪了,不得已弄了个哈希表伪装成nlogn(当然随便卡,好孩子不要学)……

    不过为啥哈希表的大小开小点就RE啊……?必须得超过数据范围一大截才行……谜

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int f,c;
    inline void R(int &x){
        c=0;f=1;
        for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
        for(x=0;c>='0'&&c<='9';c=getchar())(x*=10)+=(c-'0');
        x*=f;
    }
    #define INF 2147483647
    #define MAXN 200001
    #define MOD 200003
    #define MAXN2 290003
    typedef pair<int,int> Point;
    struct HashTable
    {
        Point v[MAXN2];
        int en,first[MOD],next[MAXN2];
        HashTable(){en=0;memset(first,-1,sizeof(first));}
        void insert(const Point &V)
          {
            int U=(int)(V.first%MOD);
            for(int i=first[U];i!=-1;i=next[i]) if(v[i].first==V.first)
    		{v[i].second=min(v[i].second,V.second); return;}
            v[en]=V; next[en]=first[U]; first[U]=en++;
          }
    }T;
    int n,K,ans=INF,last;
    int v[MAXN<<1],w[MAXN<<1],first[MAXN],next[MAXN<<1],en;
    void AddEdge(const int &U,const int &V,const int &W)
    {v[++en]=V; w[en]=W; next[en]=first[U]; first[U]=en;}
    bool centroid[MAXN];
    int size[MAXN];
    int calc_sizes(int U,int Fa)
    {
    	int res=1;
    	for(int i=first[U];i;i=next[i])
    	  if(v[i]!=Fa&&(!centroid[v[i]]))
    		res+=calc_sizes(v[i],U);
    	return size[U]=res;
    }
    Point calc_centroid(int U,int Fa,int nn)
    {
    	Point res=make_pair(INF,-1);
    	int sum=1,maxv=0;
    	for(int i=first[U];i;i=next[i])
    	  if(v[i]!=Fa&&(!centroid[v[i]]))
    	    {
    	      res=min(res,calc_centroid(v[i],U,nn));
    	      maxv=max(maxv,size[v[i]]);
    	      sum+=size[v[i]];
    	    }
    	maxv=max(maxv,nn-sum);
    	res=min(res,make_pair(maxv,U));
    	return res;
    }
    Point dis[MAXN];
    int En;
    void calc_dis(int U,int Fa,int d,int cnt)
    {
    	dis[En++]=make_pair(d,cnt);
    	for(int i=first[U];i;i=next[i])
    	  if(v[i]!=Fa&&(!centroid[v[i]]))
    	    calc_dis(v[i],U,d+w[i],cnt+1);
    }
    int calc_pairs()
    {
    	int res=0;
    	for(int i=last;i<En;++i)
    	  {
    	  	int U=(int)((K-dis[i].first)%MOD);
    	  	for(int j=T.first[U];j!=-1;j=T.next[j])
    	  	  if(T.v[j].first==K-dis[i].first)
    	  	    {
    	  	      ans=min(T.v[j].second+dis[i].second,ans);
    	  	      break;
    	  	    }
    	  }
    	for(int i=last;i<En;++i) T.insert(dis[i]);
    }
    void solve(int U)
    {
    	calc_sizes(U,-1);
    	int s=calc_centroid(U,-1,size[U]).second;
    	centroid[s]=1;
    	for(int i=first[s];i;i=next[i])
    	  if(!centroid[v[i]])
    	    solve(v[i]);
    	En=0; dis[En]=make_pair(0,0); T.insert(dis[En++]);
    	for(int i=first[s];i;i=next[i])
    	  if(!centroid[v[i]])
    	    {
    	      last=En;
    		  calc_dis(v[i],s,w[i],1);
    	      calc_pairs();
    	    }
    	for(int i=0;i<En;++i)
    	  T.first[dis[i].first%MOD]=-1;
    	T.en=0;
    	centroid[s]=0;
    }
    int main()
    {
    	int a,b,c;
    	R(n); R(K);
    	if(!K) {puts("0"); return 0;}
    	for(int i=1;i<n;++i)
    	  {
    	  	R(a); R(b); R(c);
    	  	AddEdge(a,b,c);
    	  	AddEdge(b,a,c);
    	  }
    	solve(1);
    	printf("%d
    ",ans==INF ? -1 : ans);
    	return 0;
    }
  • 相关阅读:
    HDU 2116 Has the sum exceeded
    HDU 1233 还是畅通工程
    HDU 1234 开门人和关门人
    HDU 1283 最简单的计算机
    HDU 2552 三足鼎立
    HDU 1202 The calculation of GPA
    HDU 1248 寒冰王座
    HDU 1863 畅通工程
    HDU 1879 继续畅通工程
    颜色对话框CColorDialog,字体对话框CFontDialog使用实例
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4293443.html
Copyright © 2011-2022 走看看