zoukankan      html  css  js  c++  java
  • [JZOJ100026]图--倍增

    [JZOJ100026]图--倍增

    题目链接

    太懒了,自行搜索

    分析

    裸倍增,不多说

    (fa[i][j])表示(i)(2^j)步走到的点

    (f[i][j])表示(i)(2^j)步经过边权之和

    (mi[i][j])表示(i)(2^j)步经过的边权最小值

    (fa[i][j]=fa[fa[i][j-1]][j-1])

    (f[i][j]=f[i][j-1]+f[fa[i][j-1]][j-1])

    (mi[i][j]=min(mi[i][j-1],mi[fa[i][j-1]][j-1]))

    然后一开始我(naiive)认为要找一个环上的点开始跳,于是打个了搜索,结果不知道怎么回事一直(WA),后面才学到根本不用那么麻烦...太菜了

    代码

    /*
      code by RyeCatcher
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    #include <utility>
    #include <queue>
    #include <vector>
    #include <ext/pb_ds/hash_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <iostream>
    #define DEBUG freopen("dat.in","r",stdin);freopen("wa.out","w",stdout);
    #define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
    #define ri register int
    #define ll long long
    #define ull unsigned long long
    #define SIZE 1<<22
    using std::min;
    using std::max;
    using std::priority_queue;
    using std::queue;
    using std::vector;
    using std::pair;
    using namespace __gnu_pbds;
    inline char gc(){
        static char buf[SIZE],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
    }
    #define gc getchar
    template <class T>inline void read(T &x){
        x=0;int ne=0;char c;
        while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
        while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
    }
    const int maxn=100005;
    const int inf=0x7fffffff;
    int LIM;
    int n;
    vector <int> son[maxn];
    int fa[maxn][33],mi[maxn][33];
    ll f[maxn][33],k;
    int pos[35],tot=0,cnt=0,ms=inf;
    ll ans=0;
    int main(){
    	int x,y;
    	//FO(graph);
    	freopen("wtf.out","w",stdout);
    	freopen("graph4.in","r",stdin);
    	read(n),read(k);
    	LIM=log2(k)+1;
    	for(ri i=1;i<=n;i++){
    		read(x),x++;
    		fa[i][0]=x,son[x].push_back(i);
    	}
    	for(ri i=1;i<=n;i++)read(f[i][0]),mi[i][0]=f[i][0];
    	for(ri o=1;o<=LIM;o++){
    		for(ri i=1;i<=n;i++){
    			fa[i][o]=fa[fa[i][o-1]][o-1];
    			f[i][o]=f[i][o-1]+f[fa[i][o-1]][o-1];
    			mi[i][o]=min(mi[i][o-1],mi[fa[i][o-1]][o-1]);
    		}
    	}
    	while(k){
    		if(k%2)pos[++tot]=cnt;
    		k=k>>1;
    		cnt++;
    	}
    	for(ri i=1;i<=n;i++){
    		ms=inf,ans=0,x=i;
    		for(ri j=1;j<=tot;j++){
    			ans+=f[x][pos[j]];
    			ms=min(ms,mi[x][pos[j]]);
    			x=fa[x][pos[j]];
    		}
    		printf("%lld %d
    ",ans,ms);
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:
    判断二叉树是否是完全二叉树
    二叉搜索树的第k个节点
    二叉树的深度
    二叉搜索树与双向链表
    二叉搜索树的后序遍历序列
    poj 2192 (DP)
    poj 1159 (DP LCS)
    poj 1934(LCS)
    《编程之美》读书笔记 -- 1.2中国象棋问题
    poj 1050(DP)
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/9807679.html
Copyright © 2011-2022 走看看