codeforces 1051 F
多源点最短路。
但是有限制,m - n <= 20,边数 - 点数 <= 20, 所以这个图非常的稀疏。
任意提取出一个生成树出来,LCA处理任意两点最短路。
然后再去遍历那些多余出来的点(非树边的两个端点),看他们能不能更新答案(相当于松弛)。这里跑40个最短路预处理出来(最多40个点,但是必须在原图上跑才行)。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define time _____time 6 const long long inf = 1E18; 7 struct edge { 8 long long u,v,val,next; 9 }; 10 11 edge Edge[201000]; 12 edge xdge[201000]; 13 14 int e = 0; 15 int head[100005]; 16 17 void addedge(int u,int v,int val) { 18 Edge[e].u = u; 19 Edge[e].v = v; 20 Edge[e].val = val; 21 Edge[e].next = head[u]; 22 head[u] = e++; 23 24 Edge[e].u = v; 25 Edge[e].v = u; 26 Edge[e].val = val; 27 Edge[e].next = head[v]; 28 head[v] = e++; 29 30 } 31 32 int ec = 0; 33 int head2[100005]; 34 35 void ADD(int u,int v,int val) { 36 xdge[ec].u = u; 37 xdge[ec].v = v; 38 xdge[ec].val = val; 39 xdge[ec].next = head2[u]; 40 head2[u] = ec++; 41 42 xdge[ec].u = v; 43 xdge[ec].v = u; 44 xdge[ec].val = val; 45 xdge[ec].next = head2[v]; 46 head2[v] = ec++; 47 } 48 49 int in[100005]; 50 int out[100005]; 51 int time = 0; 52 long long depth[100005]; 53 long long ST[200005*2][20]; 54 void dfs(int x,int pre) 55 { 56 in[x]=++time; 57 ST[time][0]=x; 58 for (int i = head2[x];i != -1;i = xdge[i].next) 59 if (xdge[i].v != pre){ 60 depth[xdge[i].v] = depth[x] + xdge[i].val; 61 dfs(xdge[i].v,x); 62 ST[++time][0]=x; 63 } 64 out[x]=time; 65 } 66 67 int n,m; 68 69 void Get_ST(int n){ 70 for (int i=1;i<=n;i++) 71 for (int j=1;j<20;j++){ 72 ST[i][j]=ST[i][j-1]; 73 int v=i-(1<<(j-1)); 74 if (v>0&&depth[ST[v][j-1]]<depth[ST[i][j]]) 75 ST[i][j]=ST[v][j-1]; 76 } 77 } 78 79 int RMQ(int L,int R){ 80 if(L > R) { 81 swap(L,R); 82 } 83 int val=floor(log(R-L+1)/log(2)); 84 int x=ST[L+(1<<val)-1][val],y=ST[R][val]; 85 if (depth[x]<depth[y]) 86 return x; 87 else 88 return y; 89 } 90 91 int fa[100005]; 92 int ffind(int x) { 93 if(fa[x] == x) return x; 94 else return fa[x] = ffind(fa[x]); 95 } 96 void unit(int x,int y) { 97 int fx,fy; 98 fx = ffind(x); 99 fy = ffind(y); 100 if(fx != fy) { 101 fa[fx] = fy; 102 } 103 } 104 105 struct bian { 106 int l,r,val; 107 }; 108 109 vector<bian> duo; 110 111 long long mmap[45][45]; 112 map<int,int> mp; 113 vector<int> dian; 114 115 long long dis[45][100005]; 116 int vis[100005]; 117 118 typedef pair<long long,int> pli; 119 120 void dij(int id,int s) 121 { 122 for(int i=0;i<=n+2;i++){ 123 vis[i]=0; 124 dis[id][i]=inf; 125 } 126 dis[id][s]=0; 127 priority_queue<pli,vector<pli>,greater<pli> >q; 128 q.push(pli(0,s)); 129 130 while(!q.empty()) 131 { 132 pli tmp=q.top(); 133 q.pop(); 134 int u=tmp.second; 135 if(tmp.first>dis[id][u]) continue; 136 vis[u]=1; 137 138 for(int i=head[u];i!=-1;i = Edge[i].next){ 139 int v=Edge[i].v; 140 long long w=Edge[i].val; 141 if(vis[v]) continue; 142 if(dis[id][v]>dis[id][u]+w) 143 { 144 dis[id][v]=dis[id][u]+w; 145 q.push(pli(dis[id][v],v)); 146 } 147 } 148 } 149 150 } 151 152 153 int main() { 154 155 scanf("%d %d",&n,&m); 156 int u,v; 157 for(int i = 0; i <= n; i++) { 158 fa[i] = i; 159 head[i] = -1; 160 head2[i] = -1; 161 } 162 bian xx; 163 int val; 164 for(int i = 1; i <= m; i++) { 165 scanf("%d %d %d",&u,&v,&val); 166 addedge(u,v,val); 167 if(ffind(u) != ffind(v)) { 168 unit(u,v); 169 ADD(u,v,val); 170 } 171 else { 172 dian.push_back(u); 173 dian.push_back(v); 174 } 175 } 176 177 178 sort(dian.begin(),dian.end()); 179 dian.erase(unique(dian.begin(),dian.end()),dian.end()); 180 181 for(int i=0;i<dian.size();i++){ 182 //cout<<dian[i]<<endl; 183 dij(i + 1,dian[i]); 184 } 185 186 dfs(1,0); 187 depth[0]= inf; 188 189 Get_ST(time); 190 191 192 int q; 193 scanf("%d",&q); 194 while (q--){ 195 196 int x,y; 197 scanf("%d %d",&x,&y); 198 int LCA=RMQ(in[x],in[y]); 199 long long ans = depth[x]+depth[y]-depth[LCA]*2; 200 for(int i = 0; i < dian.size(); i++) { 201 ans = min(ans,dis[i + 1][x] + dis[i + 1][y]); 202 } 203 204 printf("%lld\n",ans); 205 206 207 208 } 209 210 211 212 213 214 215 216 }