zoukankan      html  css  js  c++  java
  • CF1051F The Shortest Statement

    CF1051F The Shortest Statement

    题目描述

    You are given a weighed undirected connected graph, consisting of n n vertices and m m edges.

    You should answer q q queries, the (i) -th query is to find the shortest distance between vertices (u_i) and (v_i).

    输入输出格式

    输入格式:

    The first line contains two integers (n) and (m) ((1 le n, m le 10^5, m - n le 20)) — the number of vertices and edges in the graph.

    Next (m) lines contain the edges: the (i) -th edge is a triple of integers (v_i, u_i, d_i) ((1 le u_i, v_i le n, 1 le d_i le 10^9, u_i eq v_i)).

    This triple means that there is an edge between vertices (u_i) and (v_i) of weight (d_i) . It is guaranteed that graph contains no self-loops and multiple edges.

    The next line contains a single integer (q~(1 le q le 10^5)) — the number of queries.

    Each of the next (q) lines contains two integers (u_i) and (v_i~(1 le u_i, v_i le n)) — descriptions of the queries.

    Pay attention to the restriction (m - n ~ le ~ 20).

    输出格式:

    Print (q) lines.

    The (i) -th line should contain the answer to the (i) -th query — the shortest distance between vertices (u_i) and (v_i).


    不错的题目

    发现Pay attention...,所以肯定有用了(一般看数据范围这么奇怪也会想到吧

    思路:先跑一颗生成树,然后把不在生成树的边的端点拿出来,以每个端点跑最短路。询问直接枚举经过哪个端点或者直接是树上路径


    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define ll long long
    const int N=1e5+10;
    int n,m,Q;
    int head[N],to[N<<1],Next[N<<1],cnt=1;
    ll edge[N<<1],dis[N];
    void add(int u,int v,ll w)
    {
        to[++cnt]=v,Next[cnt]=head[u],edge[cnt]=w,head[u]=cnt;
    }
    int is[N<<1],used[N],f[N][21],dep[N];
    void dfs(int now)
    {
        for(int i=1;f[now][i-1];i++) f[now][i]=f[f[now][i-1]][i-1];
        used[now]=1;
        for(int i=head[now];i;i=Next[i])
        {
            int v=to[i];
            if(!used[v])
            {
                is[i]=is[i^1]=1;
                dis[v]=dis[now]+edge[i];
                f[v][0]=now;
                dep[v]=dep[now]+1;
                dfs(v);
            }
        }
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y]) swap(x,y);
        for(int i=20;~i;i--)
            if(dep[f[x][i]]>=dep[y])
                x=f[x][i];
        if(x==y) return x;
        for(int i=20;~i;i--)
            if(f[x][i]!=f[y][i])
                x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    int point[100],tot;
    #define P pair <ll,int>
    priority_queue <P,vector <P>,greater <P> > q;
    ll diss[100][N];
    void dijs()
    {
        memset(diss,0x3f,sizeof(diss));
        for(int i=1;i<=tot;i++)
        {
            int u=point[i];
            diss[i][u]=0;
            q.push(make_pair(0,u));
            memset(used,0,sizeof(used));
            while(!q.empty())
            {
                int now=q.top().second;
                q.pop();
                if(used[now]) continue;
                used[now]=1;
                for(int j=head[now];j;j=Next[j])
                {
                    int v=to[j];
                    if(diss[i][v]>diss[i][now]+edge[j])
                    {
                        diss[i][v]=diss[i][now]+edge[j];
                        q.push(make_pair(diss[i][v],v));
                    }
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        ll w;
        for(int u,v,i=1;i<=m;i++)
        {
            scanf("%d%d%lld",&u,&v,&w);
            add(u,v,w),add(v,u,w);
        }
        dfs(1);
        for(int u=1;u<=n;u++)
            for(int i=head[u];i;i=Next[i])
            {
                int v=to[i];
                if(!is[i]) point[++tot]=u,point[++tot]=v;
            }
        sort(point+1,point+1+tot);
        tot=unique(point+1,point+1+tot)-point-1;
        dijs();
        scanf("%d",&Q);
        for(int u,v,i=1;i<=Q;i++)
        {
            scanf("%d%d",&u,&v);
            int lca=LCA(u,v);
            ll ans=dis[u]+dis[v]-dis[lca]*2;
            for(int j=1;j<=tot;j++)
                ans=min(ans,diss[j][u]+diss[j][v]);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    2018.10.10

  • 相关阅读:
    2、Windows 系统下安装 IntelliJ IDEA
    1、IntelliJ IDEA 使用说明
    C# static的用法详解
    wpf 加载窗体界面时出现异常System.IO.FileNotFoundException
    ObservableCollection绑定到TextBox
    Lambda表达式(转载)
    C#中out和ref之间的区别 转载
    WPF序列化与反序列化
    软件版本号规范与命名原则 转载
    WPF DataGrid滚动条滑动的时候背景色错乱或显示不全
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9764256.html
Copyright © 2011-2022 走看看