zoukankan      html  css  js  c++  java
  • [BZOJ4016][FJOI2014]最短路径树问题

    bzoj
    luogu
    loj

    description

    给你一张(n)(m)条边的无向图,从(1)号点出发沿着最短路走到每一个节点,若最短路有多条则走节点编号字典序最小的那条。可以证明走过的边是一棵树。求这棵树上所有包含(k)个节点的简单路径的最长长度以及这样的路径条数。
    (nle30000,mle60000,2le k le n)

    sol

    强行二合一而已。
    先对原图跑一边(Dijkstra)求出到每个点的最短路,然后(dfs)一遍就可以把最短路树给建出来。
    对于路径统计的问题,考虑点分治,每次统计所有过重心的路径,开一个桶表示到重心经过的边数为(i)的最大长度以及方案数。每次要先更新答案再加入桶避免重复计算。

    code

    由于bzoj评测机的某种玄学操作,只要在结构体里面调用递归函数就会出错。
    所以以下这份代码无法在bzoj上AC。
    不过在luogu和loj上都可以AC呀。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    #define pi pair<int,int>
    #define mk make_pair
    const int N = 150000;
    int n,m,k;pi ans;
    void upt(pi &a,pi b){
    	if (a.first<b.first) a=b;
    	else if (a.first==b.first) a.second+=b.second;
    }
    struct Tree{
    	int to[N],nxt[N],ww[N],head[N],cnt,sz[N],w[N],vis[N],sum,root;pi f[N];
    	void link(int u,int v,int w){
    		to[++cnt]=v;nxt[cnt]=head[u];ww[cnt]=w;head[u]=cnt;
    	}
    	void getroot(int u,int fa){
    		sz[u]=1;w[u]=0;
    		for (int e=head[u];e;e=nxt[e])
    			if (to[e]!=fa&&!vis[to[e]]){
    				getroot(to[e],u);
    				sz[u]+=sz[to[e]];
    				w[u]=max(w[u],sz[to[e]]);
    			}
    		w[u]=max(w[u],sum-sz[u]);
    		if (w[u]<w[root]) root=u;
    	}
    	void query(int u,int fa,int dep,int dis){
    		upt(ans,mk(dis+f[k-dep].first,f[k-dep].second));
    		if (k==dep) return;
    		for (int e=head[u];e;e=nxt[e])
    			if (to[e]!=fa&&!vis[to[e]])
    				query(to[e],u,dep+1,dis+ww[e]);
    	}
    	void modify(int u,int fa,int dep,int dis){
    		upt(f[dep],mk(dis,1));if (k==dep) return;
    		for (int e=head[u];e;e=nxt[e])
    			if (to[e]!=fa&&!vis[to[e]])
    				modify(to[e],u,dep+1,dis+ww[e]);		
    	}
    	void clear(int u,int fa,int dep,int dis){
    		f[dep]=mk(0,0);if (k==dep) return;
    		for (int e=head[u];e;e=nxt[e])
    			if (to[e]!=fa&&!vis[to[e]])
    				clear(to[e],u,dep+1,dis+ww[e]);		
    	}
    	void solve(int u){
    		vis[u]=1;upt(f[0],mk(0,1));
    		for (int e=head[u];e;e=nxt[e])
    			if (!vis[to[e]]) query(to[e],0,1,ww[e]),modify(to[e],0,1,ww[e]);
    		for (int e=head[u];e;e=nxt[e])
    			if (!vis[to[e]]) clear(to[e],0,1,ww[e]);
    		for (int e=head[u];e;e=nxt[e])
    			if (!vis[to[e]]) root=0,sum=sz[to[e]],getroot(to[e],0),solve(root);
    	}
    	void work(){
    		w[0]=sum=n;getroot(1,0);solve(root);
    		printf("%d %d
    ",ans.first,ans.second);
    	}
    }T;
    struct Graph{
    	int to[N],nxt[N],ww[N],head[N],cnt,dis[N],vis[N],dfn[N],tim;
    	vector<int>v[N];
    	priority_queue<pi,vector<pi>,greater<pi> >Q;
    	void link(int u,int v,int w){
    		to[++cnt]=v;nxt[cnt]=head[u];ww[cnt]=w;head[u]=cnt;
    	}
    	void dfs(int u){
    		dfn[u]=++tim;
    		for (int e=head[u];e;e=nxt[e])
    			if (dis[to[e]]==dis[u]+ww[e])
    				v[u].push_back(to[e]);
    		sort(v[u].begin(),v[u].end());
    		for (int i=0,sz=v[u].size();i<sz;++i)
    			if (!dfn[v[u][i]]){
    				T.link(u,v[u][i],dis[v[u][i]]-dis[u]);
    				T.link(v[u][i],u,dis[v[u][i]]-dis[u]);
    				dfs(v[u][i]);
    			}
    	}
    	void work(){
    		memset(dis,63,sizeof(dis));
    		dis[1]=0;Q.push(mk(0,1));
    		while (!Q.empty()){
    			int u=Q.top().second;Q.pop();
    			if (vis[u]) continue;vis[u]=1;
    			for (int e=head[u];e;e=nxt[e])
    				if (dis[to[e]]>dis[u]+ww[e])
    					dis[to[e]]=dis[u]+ww[e],Q.push(mk(dis[to[e]],to[e]));
    		}
    		dfs(1);
    	}
    }G;
    int main(){
    	n=gi();m=gi();k=gi()-1;
    	for (int i=1;i<=m;++i){
    		int u=gi(),v=gi(),w=gi();
    		G.link(u,v,w);G.link(v,u,w);
    	}
    	G.work();T.work();return 0;
    }
    
  • 相关阅读:
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第4章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第3章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第1,2章 读书笔记(待更新)
    Tkinter的Message组件
    Git 实操/配置/实践
    mysq5.7.32-win安装步骤
    行为型模式之模板方法
    结构型模式之组合模式
    结构型模式之享元模式
    结构型模式之外观模式
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9247879.html
Copyright © 2011-2022 走看看