zoukankan      html  css  js  c++  java
  • zoj 3195 Design the city LCA Tarjan

    题目链接 : ZOJ Problem Set - 3195

    题目大意:

    求三点之间的最短距离

    思路:

    有了两点之间的最短距离求法,不难得出:
    对于三个点我们两两之间求最短距离 得到 d1 d2 d3
    那么最短距离就是 d = ( d1 + d2 + d3 ) / 2

    • 要注意每个数组的范围大小,因为这个问题手抖敲错,TLE+RE一整页/(ㄒoㄒ)/~~
    • 用前向星来保存边和询问,空间卡的也很严
    • 如下图所示:所求路线为紫色,等于蓝色+黄色+绿色之和的一半

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 50005;
    const int maxm = 70005;
    struct node1 {
        int next,to,w;
    } e[maxn*2];
    struct node2 {
        int next,to,id;
    } q[maxm*6];
    int n,m,head1[maxn],head2[maxn],cnt1,cnt2,vis[maxn],f[maxn],res[maxm*6],dist[maxn];
    inline void add1(int u, int v, int w) {
        e[cnt1].to=v;
        e[cnt1].w=w;
        e[cnt1].next=head1[u];
        head1[u]=cnt1++;
    }
    inline void add2(int u, int v, int id) {
        q[cnt2].to=v;
        q[cnt2].id=id;
        q[cnt2].next=head2[u];
        head2[u]=cnt2++;
    }
    inline void init() {
        cnt1=cnt2=0;
        memset(head1,-1,sizeof(head1));
        memset(head2,-1,sizeof(head2));
        memset(vis,0,sizeof(vis));
    }
    inline int Find(int x) {
        return x == f[x] ? x : f[x] = Find(f[x]);
    }
    inline void tarjan(int s) {
        vis[s]=1;
        f[s]=s;
        int t;
        for(int i=head1[s]; i!=-1; i=e[i].next) {
            if(!vis[t=e[i].to]) {
                dist[t]=dist[s]+e[i].w;
                tarjan(t);
                f[t]=s;
            }
        }
        for(int i=head2[s]; i!=-1; i=q[i].next)
            if(vis[t=q[i].to])
                res[q[i].id]=dist[s]+dist[t]-2*dist[Find(t)];
    }
    int main() {
        int cnt=0,u,v,w,x,y,z;
        while(~scanf("%d",&n)) {
            init();
            for(int i=1; i<n; ++i) {
                scanf("%d %d %d",&u,&v,&w);
                add1(u,v,w);
                add1(v,u,w);
            }
            scanf("%d",&m);
            m*=3;
            for(int i=1; i<=m; ++i) {
                scanf("%d %d %d",&x,&y,&z);
                add2(x,y,i);
                add2(y,x,i);
                ++i;
                add2(x,z,i);
                add2(z,x,i);
                ++i;
                add2(y,z,i);
                add2(z,y,i);
            }
            dist[0]=0;
            tarjan(0);
            if(!cnt) cnt++;
            else printf("
    ");
            for(int i=1; i<=m; ++i) {
                printf("%d
    ",(res[i]+res[i+1]+res[i+2])/2);
                i+=2;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    60款很酷的 jQuery 幻灯片演示和下载
    分享27款非常棒的 jQuery 表单插件
    10款新鲜出炉的 jQuery 插件
    5 个很炫的 HTML5 游戏
    12款高质量的免费 HTML 网页模板下载
    jquery插件整理篇(四)自动补全类插件
    jquery插件整理篇(三)图片展示插件
    超强1000个jquery插件!
    34个漂亮的应用程序后台管理系统界面(系列二)
    jquery插件整理篇(九)数据验证类
  • 原文地址:https://www.cnblogs.com/lemonbiscuit/p/7862350.html
Copyright © 2011-2022 走看看