zoukankan      html  css  js  c++  java
  • P4878 道路修建-美国

    http://www.tyvj.cn/p/4878道路修建

    我想我经大神点拨后终于明白了。。。回学校再写吧

    时间限制:1s

    内存限制:256MB

    【问题述】

        A国是一个商业高度发达的国家。它包含了n座城市,每座城商业都很发达。但不幸的是,A国的交通并没有像其商业那么发达,它仅仅保证了任意两座城市之间有路径存在,而且只存在唯一的一条!

       拥有雄厚经济实力的商人们决定集资修建一条路,但在修建方案上各个商人都希望新建成的道路对自己利益最大。最终他们决定造一条路,使得两个城市间所需经过道路的数量的最大值尽可能小。为此他们提出了很多修建方案,但他们并不知道每一方案新建道路后最远城市间的最大值为多少,他们有多种修建方案,你能告诉他们每一方案对应的最远城市间的最大值吗?

    【输入】

    输入文件名为road.in。

    第一行两个数n,m(1<=n、m<=3,000),分别表示城市个数和方案个数

             接下来n-1行,每行两个数x、y,表示有一条道路连接x号城市和y号城市

             m下来m行,每行两个数a、b,表示一个修建方案对应的两个城市

    【输出】

    输出文件名为road.out。

    对于每组数据输出一行,包含一个数,表示新建道路后,最远城市间所需经过的道路数量

    【输入输出样例】

    road.in

    road.out

    8 2

    1 3

    2 3

    3 4

    4 5

    5 6

    6 7

    6 8

    3 6

    1 8

    3

    5 更正

    【数据说明】

    对于40%的数据,1<=n,m<=300;

    对于另外20%的数据,数据呈一条链

    对于100%的数据,1<=n,m<=3000

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=3009; 
    int n,m;
    int h[N],nex[N*2],to[N*2],cnt;
    int f[N];
    bool vis[N];
    int dep[N],deep[N];
    int max_son[N];
    int maxn,root;
    void Add(int x,int y)
    {
        to[++cnt]=y,nex[cnt]=h[x],h[x]=cnt;
        return;
    }
    void dfs1(int x,int tot)
    {
        vis[x]=1;
        for(int i=h[x];i;i=nex[i])
        if(!vis[to[i]])    
            dfs1(to[i],tot+1);
        if(tot>maxn)    maxn=tot,root=x;
        return ;
    }
    int dfs2(int x,int tot,int last)
    {
        vis[x]=0;f[x]=last;dep[x]=tot;
        int sum=0;
        for(int i=h[x];i;i=nex[i])
        if(vis[to[i]])    
            sum=max(sum,dfs2(to[i],tot+1,x));
        sum=max(sum,tot);
        maxn=max(maxn,sum);
        max_son[x]=sum;
        return sum;
    }
    void work(int u,int v)
    {
        int t,len,ans=0;
        if(dep[u]>=dep[v])    
            t=u;else
        if(dep[v]>dep[u])
            t=v;
        int minn=min(dep[v],dep[u]);
        ans=dep[f[t]];
        ans=max(ans,(minn+1)); 
        cout<<ans<<endl;
        return ;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x,y;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            Add(x,y);Add(y,x);
        }
        f[1]=0;
        dfs1(1,0);
        maxn=0;
        dfs2(root,0,0);
        for(int i=1,u,v;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            work(u,v);
        }
        return 0;
    }
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=3009; 
    int n,m;
    int h[N],nex[N*2],to[N*2],cnt;
    int f[N];
    bool vis[N];
    int dep[N],deep[N];
    int max_son[N];
    int maxn,root;
    void Add(int x,int y)
    {    to[++cnt]=y,nex[cnt]=h[x],h[x]=cnt;}
    void dfs1(int x,int tot)
    {
        vis[x]=1;
        for(int i=h[x];i;i=nex[i])
        if(!vis[to[i]])    
            dfs1(to[i],tot+1);
        if(tot>maxn)    maxn=tot,root=x;
        return ;
    }
    int dfs2(int x,int tot,int last)
    {
        vis[x]=0;f[x]=last;dep[x]=tot;
        int sum=0;
        for(int i=h[x];i;i=nex[i])
        if(vis[to[i]])    
            sum=max(sum,dfs2(to[i],tot+1,x));
        sum=max(sum,tot);
        maxn=max(maxn,sum);
        max_son[x]=sum;
        return sum;
    }
    void work(int u,int v)
    {
        int t,len,ans=0,last;
        if(dep[u]>=dep[v])    
            t=u;else
        if(dep[v]>dep[u])
            t=v;
        int minn=min(dep[v],dep[u]);
        /*
        if(max_son[t]!=maxn)
        {
            printf("%d
    ",maxn);
            return;
        }else
        {
            int ans;
            ans=maxn-(dep[t]-minn)+1;
            ans=max(ans,minn+1+(dep[t]-minn)/2);
            printf("%d
    ",ans);
            return ;
        }
        */
        /*
        len=minn+1;last=t;
        ans=max_son[t]-(dep[t]-minn)+1;
        while(dep[t]>len)
        {
            for(int i=h[t];i;i=nex[i])
            if((to[i]!=f[t])&&(to[i]!=last))
            {
                ans=max(ans,max_son[to[i]]-(dep[t]-len));
            }
            last=t;t=f[t];len++;
        }
        */
        ans=dep[f[t]];
        
        printf("%d
    ",ans);
        return ;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x,y;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            Add(x,y);Add(y,x);
        }
        f[1]=0;
        dfs1(1,0);
        maxn=0;
        dfs2(root,0,0);
        for(int i=1,u,v;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            work(u,v);
        }
        return 0;
    }
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=3009; 
    int n,m;
    int h[N],nex[N*2],to[N*2],cnt;
    int f[N];
    bool vis[N];
    int dep[N],deep[N];
    int max_son[N];
    int maxn,root;
    void Add(int x,int y)
    {
        to[++cnt]=y,nex[cnt]=h[x],h[x]=cnt;
        return;
    }
    void dfs1(int x,int tot)
    {
        vis[x]=1;
        for(int i=h[x];i;i=nex[i])
        if(!vis[to[i]])    
            dfs1(to[i],tot+1);
        if(tot>maxn)    maxn=tot,root=x;
        return ;
    }
    int dfs2(int x,int tot,int last)
    {
        vis[x]=0;f[x]=last;dep[x]=tot;
        int sum=0;
        for(int i=h[x];i;i=nex[i])
        if(vis[to[i]])    
            sum=max(sum,dfs2(to[i],tot+1,x));
        sum=max(sum,tot);
        maxn=max(maxn,sum);
        max_son[x]=sum;
        return sum;
    }
    void work(int u,int v)
    {
        int t,len,ans=0;
        if(dep[u]>=dep[v])    
            t=u;else
        if(dep[v]>dep[u])
            t=v;
        int minn=min(dep[v],dep[u]);
        len=minn+1;
        ans=minn+1;
        ans=max(ans,max_son[t]-(dep[t]-minn-1));
        while(dep[t]>len)
        {
            ans=max(ans,max_son[t]-(dep[t]-len));
            len++,t=f[t];
        } 
        
        return ;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x,y;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            Add(x,y);Add(y,x);
        }
        f[1]=0;
        dfs1(1,0);
        maxn=0;
        dfs2(root,0,0);
        for(int i=1,u,v;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            work(u,v);
        }
        return 0;
    }
  • 相关阅读:
    C# 串口操作系列(2) -- 入门篇,为什么我的串口程序在关闭串口时候会死锁 ?
    C# 串口操作系列(1) -- 入门篇,一个标准的,简陋的串口例子。
    嵌入式
    [转] Java程序员学C#基本语法两个小时搞定(对比学习)
    test
    LeetCode 【困难】数据库-第1412 :查找成绩处于中游的学生
    LeetCode 【困难】数据库-第1384 :按照年度列出销售总额(每个产品、每年、总销额)
    LeetCode 【困难】数据库-第1369 :获取最近第二次的活动
    LeetCode 【困难】数据库-第1336(超困难):每次访问的交易次数
    LeetCode 【困难】数据库-第1225:报告系统状态的连续日期
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7624242.html
Copyright © 2011-2022 走看看