洛谷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]='\n';
 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 }

 

posted @ 2018-09-20 15:42  bztMinamoto  阅读(213)  评论(0编辑  收藏  举报
Live2D