[51nod1743]雪之国度

  雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路。
  雪之女王赋予了每一座城市不同的能量,其中第i座城市被赋予的能量为Wi。
  如果城市u和v之间有一条道路,那么只要此刻雪之女王的能量不小于|Wu-Wv|,这条道路就是安全的。
  如果城市u和v之间存在两条没有重复道路的安全路径(其中每一段道路都是安全的),则认为这两座城市之间有着良好的贸易关系。
  最近,雪之女王因为情感问题,她的能量产生巨大的波动。为了维持雪之国度的经济贸易,她希望你能帮忙对Q对城市进行调查。
  对于第j对城市uj和vj,她希望知道在保证这两座城市之间有着良好贸易关系的前提之下,自己最少需要保持多少的能量。
 Input
  每一组数据第一行有3个整数,依次为N,M,Q,表示城市个数,道路个数,和所需要进行的调查次数。
  之后一行,有N个整数,依次为每一个城市被赋予的能量Wi。
  之后M行,每一行有2个整数,表示对应编号的两个城市之间有一条道路。
  之后Q行,每一行有2个整数,表示一组调查的城市目标。
  对于100%的数据来说,3<=N<=100000, 3<=M<=500000, 1<=Q<=100000, 每一座城市的能量Wi满足0<=Wi<=200000.
 Output
  输出一共有Q行,依次对应Q次调查的结果。
  其中第j行给出了第j次调查的结果,即雪之女王需要保持的最少能量值。如果永远也无法做到,输出"infinitely"。

  就是要使俩城市在同个边双连通分量,问这个边双最大边权的最小值。

  先把最小生成树跑出来,然后把没用到的边按照边权从小到大加进去,每次可能会形成一个环,就把那个环缩成一个点,但同时要开一个新的点代表这个新形成的边双,并且新的点往环上的所有点连边(这是在一棵新的树里面做的),边权为环上的最大边权。

  那么对于每个查询的点对(a,b),答案其实就是两个点在新树上路径的最大边权(两个点在新树上的lca代表的边双就是最优的了)。

  具体实现就是倍增来倍增去的....

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cmath>
  7 #include<cstdlib>
  8 #include<bitset>
  9 //#include<ctime>
 10 #define ll long long
 11 #define ull unsigned long long
 12 #define ui unsigned int
 13 #define d double
 14 #define ld long double
 15 using namespace std;
 16 const int maxn=500233;
 17 struct zs{int x,y,dis;bool used;}a[maxn];
 18 struct zs1{int too,pre,dis;}e[maxn<<1];int tot,last[maxn];
 19 int too[maxn],pre[maxn],la[maxn],tt;
 20 int FA[100233][18],_FA[200233][18],MX[100233][18],_MX[200233][18];
 21 int id[maxn],cnt,dep[maxn],_dep[maxn],_RT[maxn],RT,fa[maxn],top[maxn],v[maxn],_V[maxn];
 22 int i,j,k,n,m;
 23 bool u[maxn];
 24
 25 int ra;char rx;
 26 inline int read(){
 27     rx=getchar(),ra=0;
 28     while(rx<‘0‘)rx=getchar();
 29     while(rx>=‘0‘)ra=ra*10+rx-48,rx=getchar();return ra;
 30 }
 31
 32
 33 bool operator <(zs a,zs b){return a.dis<b.dis;}
 34 inline int getfa(int x){return fa[x]!=x?fa[x]=getfa(fa[x]):x;}
 35 inline int gettop(int x){return top[x]!=x?top[x]=gettop(top[x]):x;}
 36 inline int abs(int x){return x<0?-x:x;}
 37
 38 inline void insert(int a,int b,int c){
 39     e[++tot].too=b,e[tot].dis=c,e[tot].pre=last[a],last[a]=tot,
 40     e[++tot].too=a,e[tot].dis=c,e[tot].pre=last[b],last[b]=tot;
 41 }
 42 inline void ins(int a,int b){too[++tt]=b,pre[tt]=la[a],la[a]=tt;/*printf("link:%d-->%d\n",a,b);*/}
 43 inline int max(int a,int b){return a>b?a:b;}
 44 inline void maxs(int &a,int b){if(b>a)a=b;}
 45 void dfs(int x){
 46     int to,i;dep[x]=dep[FA[x][0]]+1,u[x]=1;
 47     for(i=1;i<18;i++)FA[x][i]=FA[FA[x][i-1]][i-1],MX[x][i]=max(MX[x][i-1],MX[FA[x][i-1]][i-1]);
 48     for(i=last[x];i;i=e[i].pre)if(!u[to=e[i].too])
 49         FA[to][0]=x,MX[to][0]=e[i].dis,dfs(to);
 50 }
 51 inline int getmx(int x,int y){
 52     int mx=0,i;//printf("  getmx:%d  %d\n",x,y);
 53     if(dep[x]<dep[y])swap(x,y);
 54     for(i=17;i>=0;i--)if(dep[FA[x][i]]>=dep[y])maxs(mx,MX[x][i]),x=FA[x][i];
 55     if(x!=y){
 56         for(i=17;i>=0;i--)if(FA[x][i]!=FA[y][i])maxs(mx,MX[x][i]),maxs(mx,MX[y][i]),x=FA[x][i],y=FA[y][i];
 57         maxs(mx,MX[x][0]),maxs(mx,MX[y][0]);
 58     }//printf("lca:%d\n",FA[x][0]);
 59     return mx;
 60 }
 61
 62 void _dfs(int x){
 63     int i;_dep[x]=_dep[_FA[x][0]]+1,_RT[x]=RT,u[x]=1;
 64     for(i=1;i<18;i++)_FA[x][i]=_FA[_FA[x][i-1]][i-1],_MX[x][i]=max(_MX[x][i-1],_MX[_FA[x][i-1]][i-1]);
 65     for(i=la[x];i;i=pre[i])
 66         _FA[too[i]][0]=x,_MX[too[i]][0]=_V[x],_dfs(too[i]);
 67 }
 68 inline int _getmx(int x,int y){
 69     int mx=0,i;
 70     if(_dep[x]<_dep[y])swap(x,y);
 71     for(i=17;i>=0;i--)if(_dep[_FA[x][i]]>=_dep[y])maxs(mx,_MX[x][i]),x=_FA[x][i];
 72     if(x!=y){
 73         for(i=17;i>=0;i--)if(_FA[x][i]!=_FA[y][i])maxs(mx,_MX[x][i]),maxs(mx,_MX[y][i]),x=_FA[x][i],y=_FA[y][i];
 74         maxs(mx,_MX[x][0]),maxs(mx,_MX[y][0]);
 75     }return mx;//_FA[x][0]>0?mx:-1;
 76 }
 77 int main(){
 78     n=read(),m=read();int q=read();
 79     for(i=1;i<=n;i++)v[i]=read(),fa[i]=i;
 80     for(i=1;i<=m;i++)a[i].x=read(),a[i].y=read(),a[i].dis=abs(v[a[i].x]-v[a[i].y]);
 81     std::sort(a+1,a+1+m);
 82
 83     int x,y,tmp;
 84     for(i=1;i<=m;i++)if((x=getfa(a[i].x))!=(y=getfa(a[i].y)))
 85         fa[x]=y,insert(a[i].x,a[i].y,a[i].dis),a[i].used=1;//,printf("%d--%d  %d\n",a[i].x,a[i].y,a[i].dis);
 86     for(i=1;i<=n;i++)if(!u[i])dfs(i);
 87 //    for(i=1;i<=n;i++)printf("i:%d   FA:%d\n",i,FA[i][0]);
 88 //    return 233;
 89     int cnt=n;
 90     for(i=1;i<=n;i++)id[i]=top[i]=i;
 91     for(i=1;i<=m;i++)if(!a[i].used&&((x=gettop(a[i].x)))!=(y=gettop(a[i].y))){
 92 //        printf("     %d  %d     %d    x:%d  y:%d\n",a[i].x,a[i].y,a[i].dis,x,y);
 93         _V[++cnt]=max(a[i].dis,getmx(a[i].x,a[i].y));//printf("        _V:%d\n",_V[cnt]);
 94         while(x!=y){
 95             if(dep[x]<dep[y])swap(x,y);
 96             ins(cnt,id[x]),//printf("link:%d-->%d\n",cnt,id[x]),
 97             top[x]=gettop(FA[x][0]),x=top[x];//printf("        %d %d\n",x,y);
 98         }ins(cnt,id[x]),id[x]=cnt;
 99     }
100     memset(u+1,0,cnt);
101     for(i=cnt;i;i--)if(!u[i])RT=i,_dfs(i);
102
103     while(q--){
104         x=read(),y=read();
105         if(_RT[x]!=_RT[y])puts("infinitely");//else
106         //    if((tmp=_getmx(x,y))==-1)puts("infinitely");
107             else printf("%d\n",/*tmp*/_getmx(x,y));
108     }
109 }

时间: 2024-11-09 13:24:38

[51nod1743]雪之国度的相关文章

【51nod1743】雪之国度(最小生成树+倍增)

点此看题面 大致题意: 给你一张无向连通图,其中每条边的边权为这条边连接的两点的权值之差.每次询问两点之间是否存在两条不重复的路径,若存在则输出这两条路径上最大值的最小值. 大致思路 这题显然就是要让你维护边双. 我们可以先对原图求一遍最小生成树,然后再将其余非树边(按权值从小到大先排一次序)一条一条地加到图中. 对于这条边连接的两个点,我们需要对它们在树上路径进行修改. 要注意的是,对于已经修改过的,我们就不能对它进行再一次修改,因为边已经排过序,新加上的边肯定没有原来加上的边更优. 至于维护

雪漏有啲尴尬,佢畀交住都唔好走佬

雪漏有啲尴尬,佢畀交住,都唔好走佬,雪漏睇到商幸灾乐祸笑,忽然就发现小乖点都举住细,大眼都一眨一眨嘅睇住佢睇.双眼对视,小乖都恨恨嘅倔佢一眼,畀啲雪漏觉得一头雾水嘅.与其揾个生暴妹子,不如小乖嚟演戏丫嘛,雪漏就朝住小乖伸出咗手:"就系嗰个黑大个身边啲细路女."商冇计带雪漏嘅随口黑一啲,唔知咩时候就揽住楚兮一蚊睇戏,都冇起哄.灯光如柱,照喺咗小乖身上,呢个又纯又靓啲竹升妹真系超有气质嘅. https://www.huxiu.com/member/1485425/n.html 舒服,但雪漏

NYOJ20 吝啬的国度 (dfs)

题目描述: http://acm.nyist.net/JudgeOnline/problem.php?pid=20 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设你不走重复的路). 输入 第一行输入一个整数M表示测试数据共有M(1<=M<=5)组 每组测试数据的第一行输入一个正整数N(1<=N<=100000)和一个正整数S(1<

沐雪微信平台---企业微信营销专家

上海沐雪网络科技有限公司打造一个专门针对微信公众账号提供营销推广服务的第三方平台-沐雪微信http://uweixin.cn.主要功能是针对微信商家公众号提供与众不同的.有针对性的营销推广服务.通过沐雪微信平台,用户可以轻松管理自己的微信各类信息,对微信公众账号进行维护.开展智能机器人.在线发优惠劵.抽奖.刮奖.派发会员卡.打造微官网.开启微团购等多种活动,对微信营销实现有效监控,极大扩展潜在客户群和实现企业的运营目标.沐雪微信平台很好的弥补了微信公众平台本身功能不足.针对性不强.交互不便利的问

nyist 20 吝啬的国度(dfs)

吝啬的国度 题目描述: 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来. 现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市, 必须经过的前一个城市是几号城市(假设你不走重复的路). 输入: 第一行输入一个整数M表示测试数据共有M(1<=M<=5)组 每组测试数据的第一行输入一个正整数N(1<=N<=100000)和一个正整数S(1<=S<=100000),  N表示城市的总个数,S表示参观者所在城市的编号 随后

响应式下的雪碧图解决方案

一.概述 在传统的居中布局时,我们常用background-position这个属性来进行雪碧图的定位,在减少数据量的同时,保证准确定位.在移动端使用越来越重的现在,以往的传统定位,已经无法达到目的,那么是否有合适的解决方案呢?答案是有的,让我们先来了解background的两个属性: background-position:背景图片相对容器原点的起始位置.详解可以查看另一篇博客:background-position 详解. background-size: 规定背景图的尺寸: 语法:back

使用 Compass 生成雪碧图

使用 Compass 创建一个项目 要在一个新项目中使用 Compass,可以打开命令行工具并输入如下指令 compass create my-project 如果 my-project 目录不存在,上述命令会创建一个叫做 my-project 的目录,并在其中添加以下文件: 如果你没有为compass create命令传递一个目录参数,它将使用你当前所在的目录. 在config.rb文件中,你可以对Compass的一些配置进行修改,例如资源位置和压缩程度.sass目录包含了一些初始的样式表,你

前端工程师技能之photoshop巧用系列第五篇——雪碧图

显示目录 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇--雪碧图 定义 css雪碧图(sprite)是一种网页图片应用处理方式,它允许将一个页面涉及到的所有零星图片都包含到一张大图中.使用雪碧图的处理方式可以实现两个优点: [1]减少http请求次数 [2]减少图片大小,提升网页加载速度 (多张图片加载速度小于拼合成的图片的加载速度) 凡事都不完美,实现优点的同时也带来了缺点,即提

ACM/ICPC 之 经典动规(POJ1088-滑雪)

POJ1088-滑雪 将每个滑雪点都看作起点,从最低点开始逐个由四周递推出到达此点的最长路径的长度,由该点记下. 理论上,也可以将每一点都看作终点,由最高点开始计数,有兴趣可以试试. 1 //经典DP-由高向低海拔滑雪-求最长路 2 //Memory:372K Time:32 Ms 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 using