zoukankan      html  css  js  c++  java
  • cf1051F. The Shortest Statement(最短路/dfs树)

    You are given a weighed undirected connected graph, consisting of nn vertices and mm edges.

    You should answer qq queries, the ii-th query is to find the shortest distance between vertices uiui and vivi.

    Input

    The first line contains two integers n and m (1n,m105,mn20) — the number of vertices and edges in the graph.

    Next m lines contain the edges: the i-th edge is a triple of integers vi,ui,di (1≤ui,vi≤n,1≤di≤109,ui≠vi). This triple means that there is an edge between vertices ui and vi of weight di. It is guaranteed that graph contains no self-loops and multiple edges.

    The next line contains a single integer q (1q105)— the number of queries.

    Each of the next qq lines contains two integers uiui and vi (1ui,vin)vi (1≤ui,vi≤n) — descriptions of the queries.

    Pay attention to the restriction mn  20

    Output

    Print q lines.

    The i-th line should contain the answer to the i-th query — the shortest distance between vertices ui and vi.

    解题思路:

    题目非常良心地强调了m-n<=20

    建一颗dfs树,对于未加入树的边两端跑Dij

    询问只要枚举未入树边更新即可。

    代码:

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 typedef long long lnt;
      6 struct pnt{
      7     int hd;
      8     int dp;
      9     int no;
     10     int fa[22];
     11     lnt dis;
     12     lnt tds;
     13     bool vis;
     14     bool cop;
     15     bool friend operator < (pnt x,pnt y)
     16     {
     17         return x.dis>y.dis;
     18     }
     19 }p[1000000];
     20 struct ent{
     21     int twd;
     22     int lst;
     23     lnt vls;
     24 }e[1000000];
     25 std::priority_queue<pnt>Q;
     26 int n,m;
     27 int q;
     28 int cnt;
     29 int sct;
     30 lnt dist[50][200000];
     31 int sta[50];
     32 void ade(int f,int t,lnt v)
     33 {
     34     cnt++;
     35     e[cnt].twd=t;
     36     e[cnt].vls=v;
     37     e[cnt].lst=p[f].hd;
     38     p[f].hd=cnt;
     39     return ;
     40 }
     41 void Dij(int x)
     42 {
     43     if(p[x].cop)
     44         return ;
     45     p[x].cop=true;
     46     sta[++sct]=x;
     47     for(int i=1;i<=n;i++)
     48     {
     49         p[i].dis=0x3f3f3f3f3f3f3f3fll;
     50         p[i].no=i;
     51         p[i].vis=false;
     52     }
     53     p[x].dis=0;
     54     while(!Q.empty())
     55         Q.pop();
     56     Q.push(p[x]);
     57     while(!Q.empty())
     58     {
     59         x=Q.top().no;
     60         Q.pop();
     61         if(p[x].vis)
     62             continue;
     63         p[x].vis=true;
     64         for(int i=p[x].hd;i;i=e[i].lst)
     65         {
     66             int to=e[i].twd;
     67             if(p[to].dis>p[x].dis+e[i].vls)
     68             {
     69                 p[to].dis=p[x].dis+e[i].vls;
     70                 Q.push(p[to]);
     71             }
     72         }
     73     }
     74     for(int i=1;i<=n;i++)
     75         dist[sct][i]=p[i].dis;
     76     return ;
     77 }
     78 void dfs(int x,int f)
     79 {
     80     p[x].fa[0]=f;
     81     p[x].dp=p[f].dp+1;
     82     for(int i=1;i<=20;i++)
     83         p[x].fa[i]=p[p[x].fa[i-1]].fa[i-1];
     84     for(int i=p[x].hd;i;i=e[i].lst)
     85     {
     86         int to=e[i].twd;
     87         if(to==f)
     88             continue;
     89         if(p[to].tds)
     90         {
     91             Dij(x);
     92             Dij(to);
     93         }else{
     94             p[to].tds=p[x].tds+e[i].vls;
     95             dfs(to,x);
     96         }
     97     }
     98 }
     99 int Lca(int x,int y)
    100 {
    101     if(p[x].dp<p[y].dp)
    102         std::swap(x,y);
    103     for(int i=20;i>=0;i--)
    104         if(p[p[x].fa[i]].dp>=p[y].dp)
    105             x=p[x].fa[i];
    106     if(x==y)
    107         return x;
    108     for(int i=20;i>=0;i--)
    109         if(p[x].fa[i]!=p[y].fa[i])
    110         {
    111             x=p[x].fa[i];
    112             y=p[y].fa[i];
    113         }
    114     return p[x].fa[0];
    115 }
    116 int main()
    117 {
    118     scanf("%d%d",&n,&m);
    119     for(int i=1;i<=m;i++)
    120     {
    121         int a,b,c;
    122         scanf("%d%d%d",&a,&b,&c);
    123         ade(a,b,c);
    124         ade(b,a,c);
    125     }
    126     p[1].tds=1;
    127     dfs(1,1);
    128     scanf("%d",&q);
    129     while(q--)
    130     {
    131         int x,y;
    132         scanf("%d%d",&x,&y);
    133         int f=Lca(x,y);
    134         lnt ans=p[x].tds+p[y].tds-2*p[f].tds;
    135         for(int i=1;i<=sct;i++)
    136             ans=std::min(ans,dist[i][x]+dist[i][y]);
    137         printf("%I64d
    ",ans);
    138     }
    139     return 0;
    140 }
  • 相关阅读:
    问题集
    第04次作业-树
    06-图
    05-查找
    04-树
    03-栈和队列
    02-线性表
    01-抽象数据类型
    C语言--总结报告
    C语言--函数嵌套
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9857885.html
Copyright © 2011-2022 走看看