• 【nowcoder】赛前集训营5


    无形的博弈

    并不想说话 全都可以 真·无形的博弈

    int main(){
    #ifndef ONLINE_JUDGE
        freopen("T1.txt","r",stdin);
    #endif
        rd(n);
        for(int i=1;i<=n;++i) ans=(ans<<1)%P;
        printf("%d",ans);
        return 0;
    }
    

    十二桥问题

    发现桥很少 可以状压

    不想调了 92昏

    struct node{int x,y,w;}a[30];int b[30];
    
    int tot=0,head[N];
    struct edge{int v,w,nxt;}e[M<<1];
    void add(int u,int v,int w){e[++tot]=(edge){v,w,head[u]},head[u]=tot;}
    
    ll dis[N],mp[30][30];bool vis[N];
    priority_queue<pli>q;
    void dij(int s){
    	memset(vis,0,sizeof(vis)),memset(dis,inf,sizeof(dis));
    	q.push(make_pair(dis[b[s]]=0ll,b[s]));
    	while(!q.empty()){
    		int u=q.top().second;q.pop();
    		if(vis[u]) continue;
    		vis[u]=1;
    		for(int i=head[u],v;i;i=e[i].nxt)
    			if(dis[v=e[i].v]>dis[u]+e[i].w) q.push(make_pair(-(dis[v]=dis[u]+1ll*e[i].w),v));
    	}
    	for(int i=1;i<=b[0];++i) mp[s][i]=dis[b[i]];
    }
    
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("T2.txt","r",stdin);
    #endif
    	rd(n),rd(m),rd(K);
    	memset(f,inf,sizeof(f)),b[0]=0;
    	for(int i=1,u,v,w;i<=m;++i){
    		rd(u),rd(v),rd(w),add(u,v,w),add(v,u,w);
            if(i<=K) a[i]=(node){u,v,w},b[++b[0]]=u,b[++b[0]]=v;
    	}
        b[++b[0]]=1,sort(b+1,b+b[0]+1);
        b[0]=unique(b+1,b+b[0]+1)-b-1;
        for(int i=1;i<=K;++i) a[i].x=lower_bound(b+1,b+b[0]+1,a[i].x)-b,a[i].y=lower_bound(b+1,b+b[0]+1,a[i].y)-b;
    	for(int i=1;i<=b[0];++i) dij(i);
        for(int i=1;i<=K;++i)
            f[1<<(i-1)][i][0]=mp[1][a[i].y]+a[i].w,f[1<<(i-1)][i][1]=mp[1][a[i].x]+a[i].w;
        for(int i=0;i<(1<<K);++i){
            for(int j=1;j<=K;++j){
                if(!(i&(1<<(j-1)))) continue;
                for(int k=1,sta;k<=K;++k)
                if(!(i&(1<<(k-1))))
                	sta=(i|(1<<(k-1))),
                    f[sta][k][0]=min(f[sta][k][0],f[i][j][0]+mp[a[j].x][a[k].y]+a[k].w),
                    f[sta][k][0]=min(f[sta][k][0],f[i][j][1]+mp[a[j].y][a[k].y]+a[k].w),
                    f[sta][k][1]=min(f[sta][k][1],f[i][j][0]+mp[a[j].x][a[k].x]+a[k].w),
                    f[sta][k][1]=min(f[sta][k][1],f[i][j][1]+mp[a[j].y][a[k].x]+a[k].w);
            }
        }
        for(int i=1;i<=K;++i)
            ans=min(ans,min(f[(1<<K)-1][i][0]+mp[a[i].x][1],f[(1<<K)-1][i][1]+mp[a[i].y][1]));
        printf("%lld
    ",ans);
    	return 0;
    }
    

    神J上树

    树链剖分后在重链上面往下跳 剖分时处理出来(f[u][0])是第一个小于(u)的点,(g[u][0])(u)到该链上第一个小于(u)的距离

    然后询问时 先记录(y)向上跳时经历的点 然后再由(x)向下跳 先倍增跳到第一个小于它的点的后面一个点 然后再往下跳小于它的点

    int tot=0,head[N];
    struct edge{int v,w,nxt;}e[N<<1];
    void add(int u,int v,int w){e[++tot]=(edge){v,w,head[u]},head[u]=tot;}
    
    ll dis[N];
    int idx=0,dfn[N],id[N],pos[N],dep[N],fa[N],son[N],top[N],bot[N],sz[N];
    void dfs1(int u,int ff){
        fa[u]=ff,sz[u]=1,dep[u]=dep[ff]+1;
        for(int i=head[u],v,mxs=-1;i;i=e[i].nxt)
        if((v=e[i].v)!=ff)
    		dis[v]=dis[u]+e[i].w,dfs1(v,u),sz[u]+=sz[v],(mxs<sz[v])?(mxs=sz[v],son[u]=v),1:1;
    }
    stack<int>S;int f[N][21];ll g[N][21];
    void dfs2(int u,int topf){
        id[dfn[u]=++idx]=u,top[u]=topf;
        if(!son[u]){bot[u]=u;return;}
        dfs2(son[u],topf),bot[u]=bot[son[u]];
        for(int i=head[u],v;i;i=e[i].nxt)
            if((v=e[i].v)!=fa[u]&&v!=son[u]) dfs2(v,v);
        if(top[u]==u){
        	int l=dfn[u],r=dfn[bot[u]];
        	while(!S.empty()) S.pop();
        	for(int i=r;i>=l;--i){
        		while(!S.empty()&&S.top()>id[i]) S.pop();
        		if(!S.empty()) f[id[i]][0]=S.top(),g[id[i]][0]=1ll*id[i]*(dis[f[id[i]][0]]-dis[id[i]]);
        		S.push(id[i]);
    		}
    	}
    }
    void doubling(){
    	for(int j=1;j<=20;++j)
    		for(int i=1;i<=n;++i)
    			f[i][j]=f[f[i][j-1]][j-1],g[i][j]=g[f[i][j-1]][j-1]+g[i][j-1];
    }
    
    int tt,fr[N],to[N];
    ll qrange(int x,int y){
    	if(dfn[y]<dfn[x]||dfn[x]+sz[x]-1<dfn[y]) return -1;
    	tt=0;ll ans=0;
    	while(top[x]!=top[y]) to[++tt]=y,fr[tt]=top[y],y=fa[top[y]];
    	fr[++tt]=x,to[tt]=y;
    	int s,t,nw=x;
    	while(tt){
    		s=fr[tt],t=to[tt--];
    		if(s!=x) ans+=1ll*nw*(dis[s]-dis[fa[s]]);
    		for(int i=20;i>=0;--i)
    			if(f[s][i]&&f[s][i]>=nw&&dis[f[s][i]]<=dis[t])
    				ans+=1ll*nw*(dis[f[s][i]]-dis[s]),s=f[s][i];
            if(f[s][0]&&s>=nw&&dis[f[s][0]]<=dis[t]) ans+=1ll*nw*(dis[f[s][0]]-dis[s]),s=f[s][0];
            for(int i=20;i>=0;--i)
            	if(f[s][i]&&dis[f[s][i]]<=dis[t]) ans+=g[s][i],s=f[s][i];
            ans+=1ll*(nw=min(s,nw))*(dis[t]-dis[s]);
    	}
    	return ans;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("T3.txt","r",stdin);
    #endif
    	rd(n),rd(m);
    	for(int i=1,u,v,w;i<n;++i) rd(u),rd(v),rd(w),add(u,v,w),add(v,u,w);
    	dfs1(1,0),dfs2(1,1),doubling();
    	for(int i=1,x,y;i<=m;++i){
    		rd(x),rd(y);
    		if(x==y){puts("0");continue;}
    		else if(dep[x]>=dep[y]){puts("-1");continue;}
    		else if(x==1){printf("%lld
    ",dis[y]);continue;}
    		else printf("%lld
    ",qrange(x,y));
    	}
    	return 0;
    }
    
  • 相关阅读:
    jmeter之正则表达式
    python_appium搭建APP自动化测试环境
    网络编程
    四种单例模式
    Pycharm快捷键
    面向对象
    阶段性总结
    模块之numpy,pandas,matplotlib
    模块之json,pickle,os,sys,logging
    模块之Time,datatime,hashlib,hmac
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11819234.html
Copyright © 2020-2023  润新知