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 }

 

posted @ 2018-09-24 01:04  汪汪鱼  阅读(220)  评论(0编辑  收藏  举报