zoukankan      html  css  js  c++  java
  • Codeforces Gym 100015C City Driving 离线LCA

    City Driving

    题目连接:

    http://codeforces.com/gym/100015/attachments

    Description

    You recently started frequenting San Francisco in your free time and realized that driving in the city is a
    huge pain. There are only N locations in the city that interest you, though, and you have decidedtotry
    to improve your driving experience. Since you lack a GPS and cannot remember too many di!erent routes,
    you wrote down the directions and how long it takes to get between N di!erent pairs of locations (the same
    in both directions), ensuring that using only these paths you can get from any location to any other one.
    Now you are planning your trip for the weekend and you need to figureoutthefastestwaytogetbetween
    Q pairs of locations in the city using only the routes you have written down.

    Input

    The input consists of multiple test cases. The first line contains a single integer N,3 ! N ! 100,000, the
    number of locations of interest and the number of routes you wrotedown.Thenext N lines each contain
    three integers u, v,and w (1 ! w ! 1,000), indicating that you have directions from location u to location v
    and vice-versa (0-indexed) which take w time. The following line contains a single integer Q,1 ! Q ! 10,000,
    the number of pairs of locations you need to compute the travel timefor. Thenext Q lines each contain
    two integers u and v, indicating that you should find the minimum time to get from location u to location
    v. The input terminates with a line with N = 0. For example:

    Output

    For each test case, print out Q lines, one for each pair of locations u and v you are finding the fastest routes
    for. Each line should simply contain the minimum time it takes to travel from location u to location v.For
    example, the correct output for the sample input above would be:

    Sample Input

    7

    0 1 2

    0 2 3

    1 3 2

    2 3 8

    2 4 3

    3 5 1

    1 6 7

    3

    4 5

    0 6

    1 2

    0

    Sample Output

    11

    9

    5

    Hint

    题意

    给你一个n环n边的图,问你两点之间的最短路

    题解:

    随便找一个环,然后在这个环上随便去掉一条边,然后就比较这个树上的距离小,还是经过这条边的饿距离小

    比如你去掉的边是a,b,边权是w,你查询u,v

    那么你比较dis(u,v),dis(u,a)+w+dis(b,v),dis(u,b)+w+dis(a,u)就好了

    找环上的边,我推荐用并查集

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100005
    struct node
    {
        int x,y;
    };
    vector<node>G[maxn];
    int dp[18][maxn*2],dis[maxn],parent[maxn],vis[maxn],pos[maxn],res[maxn];
    int n,m,c,num,cnt,si;
    int qx=0,qy=0,qv=0;
    void init()
    {
        qx = qy = qv = 0;
        cnt = num = si = 0;
        memset(dp,0,sizeof(dp));
        memset(dis,0,sizeof(dis));
        memset(vis,0,sizeof(vis));
        memset(res,0,sizeof(res));
        memset(pos,0,sizeof(pos));
        for(int i=0;i<maxn;i++)
            G[i].clear();
    }
    int Find(int i)
    {
        if(i!=parent[i])
            parent[i]=Find(parent[i]);
        return parent[i];
    }
    void Union(int i,int j)
    {
        int x,y;
        x=Find(i);
        y=Find(j);
        if(x!=y)
            parent[x]=y;
    }
    
    void dfs3(int u,int dist)
    {
        int i,j;
        vis[u]=1;
        dis[u]=dist;
        pos[u]=cnt;
        res[si]=u;
        dp[0][cnt++]=si++;
        for(i=0;i<G[u].size();i++)
        {
            j=G[u][i].x;
            if(!vis[j])
            {
                dfs3(j,dist+G[u][i].y);
                dp[0][cnt++]=dp[0][pos[u]];
            }
        }
    }
    void rmq()
    {
        int i,j,k;
        for(i=1;(1<<i)<=n;i++)
            for(j=n-1;j>=0;j--)
            {
                k=(1<<(i-1));
                dp[i][j]=dp[i-1][j];
                if(k+j<n)
                    dp[i][j]=min(dp[i][j],dp[i-1][j+k]);
            }
    }
    int cal(int i,int j)
    {
        int k;
        if(i<j)swap(i,j);
        k=0;
        while((1<<k)<=(i-j+1))
            k++;
        k--;
        k=min(dp[k][j],dp[k][i-(1<<k)+1]);
        return res[k];
    }
    int Dis(int u,int v)
    {
        int k = cal(pos[u],pos[v]);
        return dis[u]+dis[v]-dis[k]*2;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)break;
            init();
            for(int i=0;i<=n;i++)
                parent[i]=i;
            for(int i=1;i<=n;i++)
            {
                int x,y,z;scanf("%d%d%d",&x,&y,&z);
                x++,y++;
                int p = Find(x),q = Find(y);
                if(p==q){
                    qx = x,qy = y,qv = z;
                    continue;
                }
                Union(x,y);
                G[x].push_back((node){y,z});
                G[y].push_back((node){x,z});
            }
            for(int i=1;i<=n;i++)
                if(!vis[i])
                    dfs3(i,0);
            n=n*2-1;
            rmq();
            int q;
            scanf("%d",&q);
            while(q--)
            {
                int x,y;scanf("%d%d",&x,&y);
                x++,y++;
                int res = Dis(x,y);
                res = min(res,Dis(x,qx)+Dis(y,qy)+qv);
                res = min(res,Dis(x,qy)+Dis(y,qx)+qv);
                printf("%d
    ",res);
            }
        }
    }
  • 相关阅读:
    RTP时间戳
    FAT,FAT32,NTFS单目录文件数量限制
    SWT将系统图标保存为本地文件
    HttpClient+jsoup登录+解析 163邮箱
    RTP协议分析
    Java and unsigned int, unsigned short, unsigned byte, unsigned long, etc. (Or rather, the lack thereof)
    YUV转为RGB24及IplImage格式(I420和YV12)及Java版实现
    Using a long as ArrayList index in java
    详解 SWT 中的 Browser.setUrl(String url, String postData, String[] headers) 的用法
    swt生成、jar可执行包生成.exe可执行文件(giter)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5136261.html
Copyright © 2011-2022 走看看