• 【NOIP2007提高组】树网的核


    此题不错!(可惜考场没时间打了
    两种做法哦~,有种简单但慢,有种快速但难想。。。
    先讲简单的:

    Floyd+暴判

    呵呵,标题好吓人啊。
    但其实真的很简单,经过调查研究发现,F一定是在直径上,所以所求最小偏心距也一定是在F上(也就是不可能在不是直径的路径上)。
    上标:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int d[301][301],n,s,ma=0,ans=300000;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    int main()
    {
    	freopen("core.in","r",stdin);
    	freopen("core.out","w",stdout);
    	n=read(),s=read();
    	memset(d,10,sizeof(d));
    	for (int i=1;i<=n;i++) d[i][i]=0;
    	for (int i=1,u,v;i<n;i++)
    		u=read(),v=read(),d[u][v]=d[v][u]=read();
    	for (int k=1;k<=n;k++)
    		for (int i=1;i<=n;i++) if (d[i][k]<300000)
    			for (int j=1;j<=n;j++) if (d[k][j]<300000)
    					d[i][j]=d[j][i]=min(d[i][j],d[i][k]+d[k][j]);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			if (d[i][j]<=s)
    			{
    				ma=0;
    				for (int k=1;k<=n;k++)
    					ma=max(ma,(d[i][k]+d[k][j]-d[i][j])>>1);
    				ans=min(ans,ma);
    			}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    “直径”大法

    我们可以先找到一条直径上的一点,再找到直径上的一端的点,然后暴力枚举点以及能延伸到的最远的直径上的路径,然后再搞搞求求答案即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct node{int v,fr,d;}e[601];
    int ans=1e9,rt,d[601],n,m,s,tot=0,fa[601],tail[601];
    bool bz[601];
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    void add(int u,int v,int w) {e[++tot]=(node){v,tail[u],w}; tail[u]=tot;}
    
    void dfs(int x)
    {
    	for (int p=tail[x],v;p;p=e[p].fr)
    		if ((v=e[p].v)!=fa[x] && !bz[v])
    			fa[v]=x,d[v]=d[x]+e[p].d,dfs(v);
    }
    
    int main()
    {
    	freopen("core.in","r",stdin);
    	freopen("core.out","w",stdout);
    	n=read(),s=read();
    	for (int i=1,u,v,w;i<n;i++)
    		u=read(),v=read(),w=read(),add(u,v,w),add(v,u,w);
    	rt=1;d[1]=0;fa[1]=0;dfs(1);
    	for (int i=1;i<=n;i++) rt=d[i]>d[rt] ? i:rt;
    	d[rt]=0;fa[rt]=0;dfs(rt);
    	for (int i=1;i<=n;i++) rt=d[i]>d[rt] ? i:rt;
    	for (int x=rt,j=rt;x;x=fa[x])
    	{
    		while (fa[j] && d[x]-d[fa[j]]<=s) j=fa[j];
    		ans=min(ans,max(d[j],d[rt]-d[x]));bz[x]=1;
    	}
    	for (int i=rt;i;i=fa[i]) d[i]=0,dfs(i);
    	for (int i=1;i<=n;i++) ans=max(ans,d[i]);
    	printf("%d",ans);
    	return 0;    
    }
    
    转载需注明出处。
  • 相关阅读:
    搜索入门练习题3 全组合 题解
    搜索入门练习题1 素数环 题解
    搜索入门练习题2 全排列 题解
    二分 大纲
    凸包
    快速幂&矩阵快速幂
    最长不下降子序列的优化
    poj 3190 Stall Reservations
    poj 2431 Expedition

  • 原文地址:https://www.cnblogs.com/jz929/p/11817799.html
Copyright © 2020-2023  润新知