• NOI2018d1t1 归程 (dijkstra+kruskal重构树)


    题意:给一张无向联通图,每条边有长度和高度,每次询问在高度大于p的边,从v点能到达的所有点到1号点的最短距离(强制在线)

    首先dijkstra求出每个点到1号点的距离

    易知:如果我按高度从高到低给边排序然后用kruskal的方法做出一棵生成树,那么在高度大于p的条件下,在原图中联通的两点在生成树中依旧联通

    于是就可以在做kruskal的时候建一个叫做重构树的东西,在用并查集维护联通块的同时维护一个树结构:

      对于每条边,若原本两端点u,v不连通,则新建一个节点t,设a,b为u,v在并查集中的祖先,令并查集和树结构中fa[a]=fa[b]=t,同时记下树中t的两个孩子为a,b,以及t的高度与边的高度相同

    这样,树中的每棵子树的叶节点都是连通的,并且树中深度越深,节点对应边的高度就越大

    dfs一下就可以处理出每个子树对应联通块的距1号点的最近距离。

    然后对于点v,就可以倍增找出高度恰大于p的那个节点,就是最后结果

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<queue>
      5 #include<vector>
      6 #define LL long long int
      7 #define pa pair<int,int>
      8 using namespace std;
      9 const int maxn=2e5+10,logn=18,maxm=4e5+10,inf=0x3f3f3f3f;
     10 
     11 int rd(){
     12     int x=0;char c=getchar();
     13     while(c<'0'||c>'9') c=getchar();
     14     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     15     return x;
     16 }
     17 
     18 struct Edge{
     19     int a,b,l,h,ne;
     20 }eg[maxm*2];
     21 struct Node{
     22     int fa[logn],v,h,ch[2];
     23 }tr[maxn*2];
     24 int bcj[maxn*2],tct;
     25 int N,M,Q,K,S;
     26 int egh[maxn],ect;
     27 int dis[maxn];
     28 priority_queue<pa,vector<pa>,greater<pa> > q;
     29 
     30 inline void adeg(int a,int b,int l,int h){
     31     eg[ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].h=h;eg[ect].ne=egh[a];egh[a]=ect++;
     32 }
     33 
     34 void dijkstra(){
     35     memset(dis,127,sizeof(dis));dis[1]=0;
     36     q.push(make_pair(0,1));
     37     while(!q.empty()){
     38         int p=q.top().second;q.pop();
     39         for(int i=egh[p];i!=-1;i=eg[i].ne){
     40             int b=eg[i].b;
     41             if(dis[b]>dis[p]+eg[i].l){
     42                 dis[b]=dis[p]+eg[i].l;
     43                 q.push(make_pair(dis[b],b));
     44             }
     45         }
     46     }
     47 }
     48 
     49 int getf(int x){return x==bcj[x]?x:bcj[x]=getf(bcj[x]);}
     50 
     51 void kruskal(){
     52     memset(tr,0,sizeof(tr));
     53     for(int i=1;i<=N*2;i++) bcj[i]=i,tr[i].v=inf;tct=N;
     54     for(int i=1,n=1;i<ect&&n<N;i++){
     55         int a=getf(eg[i].a),b=getf(eg[i].b);
     56         if(a==b) continue;
     57         bcj[a]=bcj[b]=++tct;
     58         tr[a].fa[0]=tr[b].fa[0]=tct;
     59         tr[tct].ch[0]=a;tr[tct].ch[1]=b;
     60         tr[tct].h=eg[i].h;n++;
     61     }
     62 }
     63 
     64 void dfs(int x){
     65     for(int i=0;i<logn-1;i++){
     66         if(!tr[tr[x].fa[i]].fa[i]) break;
     67         tr[x].fa[i+1]=tr[tr[x].fa[i]].fa[i];
     68     }
     69     if(tr[x].ch[0]){
     70         dfs(tr[x].ch[0]);dfs(tr[x].ch[1]);
     71         tr[x].v=min(tr[tr[x].ch[0]].v,tr[tr[x].ch[1]].v);
     72     }else tr[x].v=dis[x];
     73 }
     74 
     75 inline bool cmp(Edge a,Edge b){
     76     return a.h>b.h;
     77 }
     78 
     79 int query(int v,int p){
     80     for(int i=logn-1;i>=0;i--){
     81         if(tr[v].fa[i]&&tr[tr[v].fa[i]].h>p) v=tr[v].fa[i];
     82     }return tr[v].v;
     83 }
     84 
     85 int main(){
     86     int i,j,k;
     87     //freopen("return.in","r",stdin);
     88     for(int T=rd();T;T--){
     89         N=rd(),M=rd();memset(egh,-1,sizeof(egh));ect=0;
     90         for(i=1;i<=M;i++){
     91             int a=rd(),b=rd(),c=rd(),d=rd();
     92             adeg(a,b,c,d);adeg(b,a,c,d);
     93         }dijkstra();
     94         sort(eg,eg+ect,cmp);kruskal();dfs(tct);
     95         Q=rd(),K=rd(),S=rd();
     96         int lastans=0;
     97         for(i=1;i<=Q;i++){
     98             int v=(rd()+K*lastans-1)%N+1;
     99             int p=(rd()+K*lastans)%(S+1);
    100             printf("%d
    ",lastans=query(v,p));
    101         }
    102     }
    103 }
  • 相关阅读:
    格式化数据和DataBinder.Eval用法范例【转】
    动态GridView +DataTable
    Container.DataItem
    SQL自定义字段排序
    VS 2008 Web Deployment Project
    清除SQLServer日志
    SQL常用功能
    在Web应用程序中执行计划任务(多线程)
    得到临时表的列数
    用rdlc文件直接导出到excel或PDF
  • 原文地址:https://www.cnblogs.com/Ressed/p/9359340.html
Copyright © 2020-2023  润新知