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<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 typedef long long lnt;
  5 struct pnt{
  6     int hd;
  7     int val;
  8     int fa;
  9     int siz;
 10     bool vis;
 11 }p[2000000];
 12 struct ent{
 13     int twd;
 14     int lst;
 15 }e[4000000];
 16 struct int_2{
 17     int no;
 18     int vl;
 19 }tmp[2000000];
 20 int cnt;
 21 int n,m;
 22 bool cmp(int_2 x,int_2 y)
 23 {
 24     return x.vl<y.vl;
 25 }
 26 bool cmq(int_2 x,int_2 y)
 27 {
 28     return x.vl>y.vl;
 29 }
 30 void ade(int f,int t)
 31 {
 32     cnt++;
 33     e[cnt].twd=t;
 34     e[cnt].lst=p[f].hd;
 35     p[f].hd=cnt;
 36     return ;
 37 }
 38 int finf(int x)
 39 {
 40     return x==p[x].fa?x:p[x].fa=finf(p[x].fa);
 41 }
 42 int main()
 43 {
 44     scanf("%d",&n);
 45     for(int i=1;i<=n;i++)
 46     {
 47         tmp[i].no=i;
 48         scanf("%d",&tmp[i].vl);
 49         p[i].val=tmp[i].vl;
 50     }
 51     for(int i=1;i<n;i++)
 52     {
 53         int a,b;
 54         scanf("%d%d",&a,&b);
 55         ade(a,b);
 56         ade(b,a);
 57     }
 58     lnt ans1=0;
 59     std::sort(tmp+1,tmp+n+1,cmp);
 60     for(int i=1;i<=n;i++)
 61     {
 62         p[i].fa=i;
 63         p[i].siz=1;
 64         p[i].vis=false;
 65     }
 66     for(int g=1;g<=n;g++)
 67     {
 68         int x=tmp[g].no;
 69         for(int i=p[x].hd;i;i=e[i].lst)
 70         {
 71             int to=e[i].twd;
 72             if(p[to].vis==false)
 73                 continue;
 74             int ff=finf(to);
 75             ans1+=(lnt)(p[ff].siz)*(lnt)(p[x].siz)*(lnt)(p[x].val);
 76             p[x].siz+=p[ff].siz;
 77             p[ff].fa=x;
 78         }
 79         p[x].vis=true;
 80     }
 81     lnt ans2=0;
 82     std::sort(tmp+1,tmp+n+1,cmq);
 83     for(int i=1;i<=n;i++)
 84     {
 85         p[i].fa=i;
 86         p[i].siz=1;
 87         p[i].vis=false;
 88     }
 89     for(int g=1;g<=n;g++)
 90     {
 91         int x=tmp[g].no;
 92         for(int i=p[x].hd;i;i=e[i].lst)
 93         {
 94             int to=e[i].twd;
 95             if(p[to].vis==false)
 96                 continue;
 97             int ff=finf(to);
 98             ans2+=(lnt)(p[ff].siz)*(lnt)(p[x].siz)*(lnt)(p[x].val);
 99             p[x].siz+=p[ff].siz;
100             p[ff].fa=x;
101         }
102         p[x].vis=true;
103     }
104     printf("%I64d\n",ans1-ans2);
105     return 0;
106 }

猜你喜欢

转载自www.cnblogs.com/blog-Dr-J/p/9857885.html