倍增优化建图求调(大哭)
查看原帖
倍增优化建图求调(大哭)
684254
Rain_chr楼主2024/8/9 21:34

目测在图不连通的情况下有锅,但实在是看不出来了。

尽管代码长,但是我觉得整体写的还是很清晰的。

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10,M=1e6+10;
int n,m,s;
struct node
{
    int x,k;
    bool operator<(const node& y) const
    {
        return k>y.k;
    }    
};
namespace Graph
{
    vector<node> a[N<<6];
    int dis[N<<6],cnt;
    void init(){cnt=n;}
    void run()
    {
        for(int i=1;i<=cnt;i++) dis[i]=2e9;
        priority_queue<node> q;
        q.push((node){s,0});
        while(q.size())
        {
            node x=q.top();
            q.pop();
            if(dis[x.x]<=x.k) continue;
            dis[x.x]=x.k;
            for(node to:a[x.x]) q.push((node){to.x,to.k+x.k});
        }
        for(int i=1;i<=n;i++) 
            if(dis[i]!=2e9) cout<<dis[i]<<" ";
            else cout<<"-1 ";
    }
}
namespace Tree
{
    vector<int> a[N];
    int bz[20][N],d[N];
    int id1[20][N],id2[20][N];
    void dfs(int x,int fa)
    {
        bz[0][x]=fa;
        d[x]=d[fa]+1;
        if(fa)
        {
            id1[0][x]=++Graph::cnt;
            id2[0][x]=++Graph::cnt;
            Graph::a[id1[0][x]].push_back((node){x,0});
            Graph::a[id1[0][x]].push_back((node){fa,0});
            Graph::a[x].push_back((node){id2[0][x],0});
            Graph::a[fa].push_back((node){id2[0][x],0});
        }
        for(int to:a[x])
        {
            if(to==fa) continue;
            dfs(to,x);
        }
    }
    int lca(int x,int y)
    {
        if(d[x]<d[y]) swap(x,y);
        for(int i=log2(d[x]);i>=0;i--)
            if(d[bz[i][x]]>=d[y])
                x=bz[i][x];
        if(x==y) return x;
        for(int i=log2(d[x]);i>=0;i--)
            if(bz[i][x]!=bz[i][y])
                x=bz[i][x],y=bz[i][y];
        return bz[0][x];
    }
    void init()
    {
        for(int i=1;(1<<i)<=n;i++)
            for(int j=1;j<=n;j++)
            {
                bz[i][j]=bz[i-1][bz[i-1][j]];
                id1[i][j]=++Graph::cnt;
                id2[i][j]=++Graph::cnt;
                Graph::a[id1[i][j]].push_back((node){id1[i-1][j],0});
                if(bz[i-1][j]) Graph::a[id1[i][j]].push_back((node){id1[i-1][bz[i-1][j]]});
                Graph::a[id2[i-1][j]].push_back((node){id2[i][j],0});
                if(bz[i-1][j]) Graph::a[id2[i-1][bz[i-1][j]]].push_back((node){id2[i][j],0});
            }
    }
    void jump(int& x,int d)
    {
        for(int i=log2(d);i>=0;i--)
            if(d>=(1>>i))
                x=bz[i][x],d-=1<<i;
    }
    void link1(int x,int y,int id,int w) //保证y是x的祖先
    {
        if(x==y) 
        {
            Graph::a[id].push_back((node){x,w});
            return ;
        }
        int lg=log2(d[x]-d[y]);
        Graph::a[id].push_back((node){id1[lg][x],w});
        jump(x,d[x]-d[y]-(1<<lg));
        Graph::a[id].push_back((node){id1[lg][x],w});
    }
    void link2(int x,int y,int id,int w) //保证y是x的祖先
    {
        if(x==y)
        {
            Graph::a[x].push_back((node){id,w});
            return ;
        }
        int lg=log2(d[x]-d[y]);
        Graph::a[id2[lg][x]].push_back((node){id,w});
        jump(x,d[x]-d[y]-(1<<lg));
        Graph::a[id2[lg][x]].push_back((node){id,w});
    }
}
namespace init
{
    struct Ask
    {
        int x1,y1,x2,y2,w;
    }ask[M];
    int fa[N];
    int find(int x)
    {
        if(fa[x]==x) return x;
        return fa[x]=find(fa[x]);
    }
    void main()
    {
        cin>>n>>m>>s;
        Graph::init();
        for(int i=1;i<=n;i++) fa[i]=i;
        int c=0;
        while(m--)
        {
            int op,x1,y1,x2,y2,w;
            cin>>op>>x1>>y1;
            if(op==1)
            {
                cin>>x2>>y2>>w;
                if(find(x1)!=find(y1)||find(x2)!=find(y2)) continue;
                ask[++c]=(Ask){x1,y1,x2,y2,w};
            }
            else
            {
                cin>>w;
                if(find(x1)==find(y1)) continue;
                Graph::a[x1].push_back((node){y1,w});
                Graph::a[y1].push_back((node){x1,w});
                Tree::a[x1].push_back(y1);
                Tree::a[y1].push_back(x1);
                fa[find(x1)]=find(y1);
            }
        }
        for(int i=1;i<=n;i++)
            if(find(i)==i)
                Tree::dfs(i,0);
        Tree::init();
        for(int i=1;i<=c;i++)
        {
            int id=++Graph::cnt;
            int k=Tree::lca(ask[i].x1,ask[i].y1);
            Tree::link2(ask[i].x1,k,id,ask[i].w);
            Tree::link2(ask[i].y1,k,id,ask[i].w);
            k=Tree::lca(ask[i].x2,ask[i].y2);
            Tree::link1(ask[i].x2,k,id,0);
            Tree::link1(ask[i].y2,k,id,0);
        }
    }
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    init::main();
    Graph::run();
    return 0;
}
2024/8/9 21:34
加载中...