zoukankan      html  css  js  c++  java
  • [IOI2011]Race

    给一棵树,每条边有权。求一条简单路径,权值和等于 K ,且边的数量最小。

    淀粉质的题,直接套淀粉质的板子,再维护一个桶,表示到达dis的最小需要的路径。
    但是有个奇怪的东西,就是如果我最后还原的时候用栈储存所有的dis就会WA4个点,但是如果我把dfs重做一遍就没事了。。。WA了1页。。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,k,head[200005],ecnt,rt,f[200005],siz[200005],size;
    struct Edge{int to,nxt,val;}e[400005];
    bool vis[200005];
    void add(int bg,int ed,int val) {e[++ecnt]=(Edge){ed,head[bg],val};head[bg]=ecnt;}
    void barycenter(int x,int fa) {
        f[x]=0,siz[x]=1;
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;
            if(v==fa||vis[v]) continue;
            barycenter(v,x),f[x]=max(f[x],siz[v]),siz[x]+=siz[v];
        }
        f[x]=max(f[x],size-siz[x]);
        if(f[x]<f[rt]) rt=x;
    }
    int dis[1000005],stk[1000005],top,ans;
    bool used[1000005];
    void dfs(int x,int fa,int val,int along) {
        dis[val]=min(dis[val],along);
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;
            if(vis[v]||v==fa) continue;
            if(val+e[i].val<=k)
            dfs(v,x,val+e[i].val,along+1);
        }
    }
    void calc(int x,int fa,int val,int dep) {
        if(val==k) ans=min(ans,dep),dis[k]=min(dis[k],dep);
        ans=min(ans,dis[k-val]+dep);
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;
            if(vis[v]||v==fa) continue;
            if(val+e[i].val<=k) calc(v,x,val+e[i].val,dep+1);
        }
    }
    void dfs2(int x,int fa,int val) {
        dis[val]=0x3f3f3f3f;
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;
            if(vis[v]||v==fa)continue;
            if(val+e[i].val<=k) dfs2(v,x,e[i].val+val);
        }
    }
    void work(int x) {
        top=0;dis[0]=0;
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;
            if(vis[v]) continue;
            if(e[i].val<=k)
            calc(v,x,e[i].val,1),dfs(v,x,e[i].val,1);
        }
        for(int i=head[x];i;i=e[i].nxt){
        	int v=e[i].to;
        	if(vis[v]) continue;
        	dfs2(v,x,e[i].val);
        }
    }
    void solve(int x) {
        vis[x]=1;
        work(x);
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;rt=0;
            if(vis[v]) continue;
            siz[rt]=size=siz[v];
            barycenter(v,0);
            solve(rt);
        }
    }
    int main() {
        scanf("%d%d",&n,&k);
        memset(dis,0x3f,sizeof dis);dis[0]=0;ans=n;
        for(int i=1,a,b,c;i<n;i++) {scanf("%d%d%d",&a,&b,&c);add(a+1,b+1,c);add(b+1,a+1,c);}
        size=n,f[0]=n;rt=0;
        barycenter(1,0);
        solve(rt);
        if(ans!=n)cout<<ans;
        else cout<<-1;
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    [AngularFire 2] Protect Write Access Using Security Rules
    [Ramda] Handle Branching Logic with Ramda's Conditional Functions
    [Angular2 Router] Setup page title with Router events
    [HTML] Creating visual skip links in HTML and CSS
    [AngularFire2] Signup and logout
    [AngularFire2] Building an Authentication Observable Data Service
    [Swift] Add Scroll View
    [Swift] Storyboard outlet and action
    [AngularFire2] Auth with Firebase auth -- email
    网站优化与Cdn文件传输服务
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9498640.html
Copyright © 2011-2022 走看看