• ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA)


    题意:一个N*M的矩形,每个格点到其邻近点的边有其权值,需要构建出一个迷宫,使得构建迷宫的边权之和最小,之后Q次查询,每次给出两点坐标,给出两点之间的最短路径
    分析:可以把每个格点视作视作图的点,隔开两点的边视作图的边,则构建迷宫可以视作求其生成树,剩余的边就是组成迷宫的墙.因为要花费最小,所以使删去的墙权置最大即可,呢么就是求最大生成树即可.
    然后每次查询相当于查这个最大生成树上任意两点的最短距离,到这一步就是个LCA板子题了.
    所以:最大生成树+树上两点最短距离
    --来自罗神

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=250005;
    struct node{
    	int v,dis,next;
    }edges[N<<1];
    int head[N],e;
    int id[N]; //节点第一次被遍历的顺序
    int dis[N]; //节点到根节点的距离
    int RMQ[N*3][20];
    int curID;
    //F[i]表示第i个遍历的节点
    //B[i]表示F[i]在树中的深度
    int F[N*3],B[N*3];
    int root;
    void init()
    {
        e = 0; curID = 0;
        memset(head,-1,sizeof(head));
    }
    void Add (int u,int v,int dis)
    {
    	edges[e].v=v;
    	edges[e].dis=dis;
    	edges[e].next=head[u];
    	head[u]=e++;
    }
    
    void DFS (int u,int p,int Dep,int d)
    {
    	int i,v;
    	curID++;
    	F[curID]=u;
    	B[curID]=Dep;
    	id[u]=curID;
    	dis[u]=d;
    	for (i=head[u];i!=-1;i=edges[i].next){
    		v=edges[i].v;
    		if (v==p) continue;
    		DFS(v,u,Dep+1,d+1);
    		curID++;
    		F[curID]=u;
    		B[curID]=Dep;
    	}
    }
    
    void initRMQ ()
    {
    	int i,j,x,y;
    	for (i=1;i<=curID;i++)
    		RMQ[i][0]=i;
    	for (j=1;(1<<j)<=curID;j++)
    		for (i=1;i+(1<<j)-1<=curID;i++){
    			x=RMQ[i][j-1];
    			y=RMQ[i+(1<<(j-1))][j-1];
    			RMQ[i][j]=B[x]<B[y]?x:y;
    		}
    }
    
    int getLCA (int a,int b)
    {
    	int k,x,y;
    	a=id[a];b=id[b];
    	if (a>b)
    		k=a,a=b,b=k;
    	k=log(1.0+b-a)/log(2.0);
    	x=RMQ[a][k];
    	y=RMQ[b-(1<<k)+1][k];
    	return B[x]<B[y]?F[x]:F[y];
    }
    
    int dist(int x,int y)
    {
        return dis[x] +dis[y] - 2*dis[getLCA(x,y)];
    }
    
    struct Edg{
        int u,v;
        LL dist;
        bool operator<(const Edg &rhs)const{return dist>rhs.dist;}
    };
    
    struct Kruskal{
        int n,m;
        Edg edges[N<<1];
        int fa[N];
        int findset(int x){ return fa[x]==-1?x:fa[x]=findset(fa[x]); }
    
        void init(int n){
            this->n=n;
            m=0;
            memset(fa,-1,sizeof(fa));
        }
    
        void AddEdge(int u,int v,LL dist){
            edges[m++] = (Edg){u,v,dist};
        }
    
        void kruskal(){
            LL sum=0;
            int cnt=0;
            sort(edges,edges+m);
            for(int i=0;i<m;i++){
                int u=edges[i].u, v=edges[i].v;
                if(findset(u) != findset(v)){
                    Add(u,v,1);
                    Add(v,u,1);
                    sum +=edges[i].dist;
                    fa[findset(u)] = findset(v);
                    if(++cnt>=n-1) return ;
                }
            }
            return ;
        }
    }G;
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int n,m;
        char c1,c2;
        LL w1,w2;
        while(scanf("%d %d",&n,&m)==2){
            init();
            G.init(n*m+1);
            for(int i=1;i<=n;++i){
                for(int j=1;j<=m;++j){
                    scanf("
    %c %lld %c %lld",&c1,&w1,&c2,&w2);
                    if(c1=='D'){
                        G.AddEdge((i-1)*m+j,i*m+j,w1);
                    }
                    if(c2 == 'R'){
                        G.AddEdge((i-1)*m+j,(i-1)*m+j+1,w2);
                    }
                }
            }
            G.kruskal();
            root=1;
            DFS(root,0,0,0);
            initRMQ();
            int Q; scanf("%d",&Q);
            int x1,y1,x2,y2;
            while(Q--){
                scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
                int u = (x1-1)*m+y1, v = (x2-1)*m+y2;
                printf("%d
    ",dist(u,v));
            }
        }
        return 0;
    }
    
    
    为了更好的明天
  • 相关阅读:
    JavaSE 基础 第54节 继承Thread类创建线程
    flask 项目部分业务逻辑
    js生成随机的uuid
    增量式爬虫
    分布式爬虫
    scrapy 的分页爬取 CrawlSpider
    scrapy 请求传参
    scrapy增加爬取效率
    scrapy框架
    模拟登陆request-session
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9614184.html
Copyright © 2020-2023  润新知