cf1051F. The Shortest Statement(最短路/dfs树)
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<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\n",ans); 138 } 139 return 0; 140 }