• 2016四川省赛 Floyd-Warshall


    这题真的有毒
    首先你忽略 N-M < 100 的条件你就gg吧
    其次就算你知道了怎么做之后
    还有可能因为写vector或者各种常数大的原因被卡

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pi;
    const int MAXN = 1e5+205;
    
    int N,M,Q;
    struct Node{
        int to,nex;
    }mip[MAXN*2], vic[MAXN*2];
    int mp[MAXN]; int mot;
    int vc[MAXN]; int vot;
    
    int vis[MAXN];
    int pre[MAXN];
    
    int tag[MAXN]; 
    int po[MAXN]; int po_cc; int cc;
    void add1(int x,int y) {
        mip[mot].to = y; mip[mot].nex = mp[x]; mp[x] = mot++;
        mip[mot].to = x; mip[mot].nex = mp[y]; mp[y] = mot++;
    }
    void add2(int x,int y) {
        vic[vot].to = y; vic[vot].nex = vc[x]; vc[x] = vot++;
        vic[vot].to = x; vic[vot].nex = vc[y]; vc[y] = vot++;
    }
    map< pair<int,int>, int> mmp;
    int dis[205][MAXN];
    /*************LCA***************/
    const int DEG=20;
    int fa[MAXN][DEG];
    int deg[MAXN];
    void BFS(int rt) {
        queue<int> qq;
        deg[rt] = 0;
        fa[rt][0] = rt;
        qq.push(rt);
        while(!qq.empty()){
            int tmp = qq.front(); qq.pop();
            for(int i = 1; i < DEG; ++i)
                fa[tmp][i] = fa[fa[tmp][i-1]][i-1];
            for(int i = vc[tmp]; i !=-1; i = vic[i].nex) {
                int v = vic[i].to; if(v == fa[tmp][0]) continue;
                deg[v] = deg[tmp]+1; fa[v][0]=tmp;
                qq.push(v);
            }
        }
    }
    int LCA(int u,int v) {
        if(deg[u] > deg[v]) swap(u,v);
        int hu = deg[u], hv = deg[v];
        int tu = u, tv = v;
        for(int det = hv-hu, i=0; det; det>>=1, ++i) {
            if(det&1) {
                tv = fa[tv][i];
            }
        }
        if(tu == tv) return tu;
        for(int i = DEG-1; i >= 0; --i) {
            if(fa[tu][i] == fa[tv][i]) continue;    
            tu = fa[tu][i]; 
            tv = fa[tv][i];
        }
        return fa[tu][0];
    }
    /*****makedis**********/
    void solve(int x) {
        memset(vis,0,sizeof(vis));
        queue<int> qq;
        qq.push(x); dis[cc][x] = 0; vis[x] = 1; pre[x]=x;
        while(!qq.empty()) {
            int b = qq.front(); qq.pop();
            for(int i = mp[b]; i != -1; i = mip[i].nex) {
                int y = mip[i].to;
                if(!vis[y]) {
            //      if(!cc) printf("hh %d %d
    ",b,y);
                    dis[cc][y] = dis[cc][b]+1; vis[y] = 1; pre[y]=b;
                    if(!cc) {
                        add2(b,y);
                    }
                    qq.push(y);
                }else if(pre[b] != y && !cc) {
            //      printf("%d %d
    ",b,y);
                    tag[b]++; if(tag[b] == 1) po[++po_cc] = b;
                    tag[y]++; if(tag[y] == 1) po[++po_cc] = y;
                }
            }
        }
    }
    int doo(int x,int y) {
        int tt = LCA(x,y);
        int ans = -dis[0][tt]*2 + dis[0][x] + dis[0][y];
        if(tt == x || tt == y) return ans;
        for(int i = 1; i <= po_cc; ++i) {
            ans = min(ans, dis[i][x]+dis[i][y]);
        } 
        return ans;
    }
    int main(){
        while(~scanf("%d %d %d",&N,&M,&Q)) {
            memset(mp,-1,sizeof(mp)); mot = 0;
            memset(vc,-1,sizeof(vc)); vot = 0;
            memset(tag,0,sizeof(tag));
            mmp.clear(); po_cc = 0; cc = 0;
            for(int i = 1; i <= M; ++i) {
                int a,b; scanf("%d %d",&a,&b);
                if(a > b) swap(a,b);
                if( a == b || mmp[pi(a,b)] ) continue;
                add1(a,b);
                mmp[pi(a,b)] ++;
            }
    
            solve(1);
            BFS(1); 
            for(int i = 1; i <= po_cc; ++i) {
                cc++; solve(po[i]);
            }
            for(int i = 0; i < Q; ++i) {
                int a,b; scanf("%d %d",&a,&b);
                printf("%d
    ",doo(a,b));
            }
        }
        return 0;
    }
  • 相关阅读:
    Cypress安装使用(E2E测试框架)
    AirtestIDE详解(跨平台的UI自动化编辑器)
    Linux之自动化部署
    工作笔记 之 Python应用技术
    工作笔记 之 Linux服务搭建
    工作笔记 之 互联网实用技术
    Git全面应用
    Python-Thread(通俗易懂)
    php笔记(二)PHP类和对象之Static静态关键字
    php笔记(一)面向对象编程
  • 原文地址:https://www.cnblogs.com/Basasuya/p/8433741.html
Copyright © 2020-2023  润新知