题意:给你一个N边形, 然后这个n边形有n-3条边,然后询问2点之间的最短路。

题解:分治。

我们可以找到一条边,使得这幅图能分成大小相同的2幅图,那么我们就可以确定那些被分割开的询问的答案是多少了。

我们假定u v是分开的, 然后我们从u点bfs一遍现在的图,v点bfs一遍现在的图,确定所有点离这2个点的位置,对于切断的询问更新答案。

需要注意的就是,每次都一定要重新建图,免得遍历太多的没有用的边。

递归结束的时候是这幅图只有3个点了,如果在3个点中的最短路,那么一定是1,假定2点不重合。

代码1:离线写法

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("distance.in","r",stdin); freopen("distance.out","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
struct Node{
    int u, v, id;
};
vector<int> vc[N][2], ee[N];
vector<pll> e[N][2];
vector<Node> q[N][2];
int ans[N], pos[N], num[N];
int lf[N], rt[N], ok[N];
int d[N][2];
queue<int> que;
void bfs(int b, int id){
    d[b][id] = 0;
    que.push(b);
    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(auto v : ee[u]){
            if(d[v][id] > d[u][id]+1){
                d[v][id] = d[u][id]+1;
                que.push(v);
            }
        }
    }
}
void solve(int k, int op){
    if(vc[k][op].size() <= 3 || q[k][op].size() == 0) return ;
    int nodes = vc[k][op].size();
    for(int i = 0; i < nodes; ++i){
        ee[i].clear();
        pos[vc[k][op][i]] = i;
        d[i][0] = d[i][1] = inf;
        ee[i].pb((i+1)%nodes);
        ee[i].pb((i-1+nodes)%nodes);
    }
    int Max = inf, id = 0;
    for(int i = 0; i < e[k][op].size(); ++i){
        int u = e[k][op][i].fi, v = e[k][op][i].se;
        int tmp = max(pos[v]-pos[u], nodes - pos[v]+pos[u]);
        if(tmp < Max) {
            Max = tmp;
            id = i;
        }
        ee[pos[u]].pb( pos[v]);
        ee[pos[v]].pb( pos[u]);
    }
    vc[k+1][0].clear(); vc[k+1][1].clear();
    q[k+1][1].clear(); q[k+1][0].clear();
    e[k+1][0].clear(); e[k+1][1].clear();
    int tu = e[k][op][id].fi, tv = e[k][op][id].se;
    for(int i = 0; i < nodes; ++i){
        if(vc[k][op][i] == tu || vc[k][op][i] == tv){
            vc[k+1][0].pb(vc[k][op][i]);
            vc[k+1][1].pb(vc[k][op][i]);
        }
        else if(vc[k][op][i] < tu || vc[k][op][i] > tv)
            vc[k+1][0].pb(vc[k][op][i]), lf[vc[k][op][i]] = 1;
        else
            vc[k+1][1].pb(vc[k][op][i]), rt[vc[k][op][i]] = 1;
    }
    bfs(pos[tu], 0);
    bfs(pos[tv], 1);
    for(int i = 0, u, v; i < e[k][op].size(); ++i){
        u = e[k][op][i].fi, v = e[k][op][i].se;
        if(lf[u] || lf[v]) e[k+1][0].pb(e[k][op][i]);
        else if(rt[u] || rt[v]) e[k+1][1].pb(e[k][op][i]);
    }
    for(int i = 0, u, v, aid; i < q[k][op].size(); ++i){
        u = q[k][op][i].u, v = q[k][op][i].v, aid = q[k][op][i].id;
        if(lf[u] && lf[v]) {
            q[k+1][0].pb(q[k][op][i]);
            continue;
        }
        else if(rt[u] && rt[v]){
            q[k+1][1].pb(q[k][op][i]);
            continue;
        }
        u = pos[u], v = pos[v];
        ans[aid] = min(d[u][1]+d[v][1], d[u][0] + d[v][0]);
    }
    for(auto v : vc[k][op]){
        lf[v] = rt[v] = 0;
        ok[v] = 0;
    }
    solve(k+1, 0);
    solve(k+1, 1);
}
int main(){
    Fopen;
    int n, m, u, v;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i){
        vc[0][0].pb(i);
    }
    for(int i = 1; i <= n - 3; ++i){
        scanf("%d%d", &u, &v);
        if(u > v) swap(u,v);
        e[0][0].pb({u,v});
    }
    scanf("%d", &m);
    for(int i = 1; i <= m; ++i){
        scanf("%d%d", &u, &v);
        if(u > v) swap(u,v);
        if(u == v)
            continue;
        q[0][0].pb({u,v,i});
    }
    solve(0,0);
    for(int i = 1; i <= m; ++i){
        printf("%d\n", ans[i]);
    }
    return 0;
}
View Code

相关文章:

  • 2022-12-23
  • 2021-10-28
  • 2022-12-23
  • 2021-05-03
  • 2022-12-23
  • 2022-12-23
  • 2021-05-20
  • 2022-12-23
猜你喜欢
  • 2021-05-28
  • 2021-06-14
  • 2022-12-23
  • 2021-06-17
  • 2021-08-27
  • 2021-08-03
  • 2022-12-23
相关资源
相似解决方案