zoukankan      html  css  js  c++  java
  • 洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)

    传送门

    前置技能,克鲁斯卡尔重构树

    我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树

    那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价)

    可以一开始直接跑一个dijkstra(关于SPFA,他死了)

    然后一遍树形dp就可以了

      1 //minamoto
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdio>
      6 #include<queue>
      7 using namespace std;
      8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      9 char buf[1<<21],*p1=buf,*p2=buf;
     10 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
     11 inline int read(){
     12     #define num ch-'0'
     13     char ch;bool flag=0;int res;
     14     while(!isdigit(ch=getc()))
     15     (ch=='-')&&(flag=true);
     16     for(res=num;isdigit(ch=getc());res=res*10+num);
     17     (flag)&&(res=-res);
     18     #undef num
     19     return res;
     20 }
     21 char sr[1<<21],z[20];int C=-1,Z;
     22 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
     23 inline void print(int x){
     24     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
     25     while(z[++Z]=x%10+48,x/=10);
     26     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
     27 }
     28 const int N=800005;
     29 struct EE{
     30     int u,v,h;
     31     EE(){}
     32     EE(int u,int v,int h):u(u),v(v),h(h){}
     33     inline bool operator <(const EE &b)const
     34     {return h>b.h;}
     35 }E[N];
     36 struct node{
     37     int u,dis;
     38     node(){}
     39     node(int u,int dis):u(u),dis(dis){}
     40     inline bool operator <(const node &b)const
     41     {return dis>b.dis;}
     42 };
     43 int head[N],Next[N],ver[N],edge[N],tot;
     44 int hc[N],nc[N],vc[N],tc;
     45 int val[N],f[N][25],fa[N],dis[N],vis[N],mn[N],bin[25];
     46 int n,m,ans,k;
     47 priority_queue<node> q;
     48 inline void clear(){
     49     memset(head,0,sizeof(head)),tot=0;
     50     memset(hc,0,sizeof(hc)),tc=0;
     51     memset(mn,0x3f,sizeof(mn));
     52     memset(f,0,sizeof(f));
     53 }
     54 inline void add(int u,int v,int e){
     55     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
     56 }
     57 inline void addc(int u,int v){
     58     vc[++tc]=v,nc[tc]=hc[u],hc[u]=tc;
     59 }
     60 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
     61 inline void mission(int u){
     62     for(int i=1;bin[i]<=n;++i)
     63     f[u][i]=f[f[u][i-1]][i-1];
     64 }
     65 void dijkstra(int s=1){
     66     memset(vis,0,sizeof(vis));
     67     memset(dis,0x3f,sizeof(dis));
     68     q.push(node(s,0)),dis[s]=0;
     69     while(!q.empty()){
     70         int u=q.top().u;q.pop();
     71         if(vis[u]) continue;
     72         vis[u]=1;
     73         for(int i=head[u];i;i=Next[i]){
     74             int v=ver[i];
     75             if(cmin(dis[v],dis[u]+edge[i])) q.push(node(v,dis[v]));
     76         }
     77     }
     78     memcpy(mn+1,dis+1,sizeof(int)*(n));
     79 }
     80 void dfs(int u){
     81     mission(u);
     82     for(int i=hc[u];i;i=nc[i]){
     83         int v=vc[i];
     84         dfs(v),cmin(mn[u],mn[v]);
     85     }
     86 }
     87 inline int query(int u,int x){
     88     for(int i=19;~i;--i)
     89     if(f[u][i]&&val[f[u][i]]>x) u=f[u][i];
     90     return mn[u];
     91 }
     92 void kruskal(){
     93     int cnt=n;
     94     for(int i=1;i<=(n<<1);++i) fa[i]=i;
     95     sort(E+1,E+1+m);
     96     for(int i=1;i<=m;++i){
     97         int u=find(E[i].u),v=find(E[i].v);
     98         if(u!=v){
     99             val[++cnt]=E[i].h;
    100             f[u][0]=f[v][0]=cnt,fa[u]=fa[v]=cnt;
    101             addc(cnt,u),addc(cnt,v);
    102             if(cnt-n==n-1) break;
    103         }
    104     }
    105     dfs(cnt);
    106 }
    107 int main(){
    108 //    freopen("testdata.in","r",stdin);
    109     int T=read();
    110     bin[0]=1;for(int i=1;i<=23;++i) bin[i]=bin[i-1]<<1;
    111     while(T--){
    112         n=read(),m=read(),ans=0;
    113         clear();
    114         for(int i=1,u,v,e,h;i<=m;++i){
    115             u=read(),v=read(),e=read(),h=read(),E[i]=EE(u,v,h);
    116             add(u,v,e),add(v,u,e);
    117         }
    118         dijkstra();
    119         kruskal();
    120         int q=read(),k=read(),s=read();
    121         while(q--){
    122             int u=(k*ans+read()-1)%n+1,v=(k*ans+read())%(s+1);
    123             print(ans=query(u,v));
    124         }
    125     }
    126     Ot();
    127     return 0;
    128 }
  • 相关阅读:
    HTML <form> 标签的 method 属性(20161028)
    PHP数据访问增删查(20161028)
    PHP数据访问基础知识(20161028)
    java代理机制
    java 模拟实现消费者和生产者问题
    Single Number II
    从1到1000中随机取出900个不重复的随机数
    取苹果方式总数
    Net-SNMP(V3协议)安装配置笔记(CentOS 5.2)(转)
    单例模式
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9681280.html
Copyright © 2011-2022 走看看