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 (1≤n,m≤105,m−n≤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 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 (1≤q≤105)— the number of queries.
Each of the next qq lines contains two integers uiui and vi (1≤ui,vi≤n)vi (1≤ui,vi≤n) — descriptions of the queries.
Pay attention to the restriction m−n ≤ 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 }