雪之国度有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代表的边双就是最优的了)。
具体实现就是倍增来倍增去的....
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ",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 ",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 ",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 ",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 ",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 ",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 ",_V[cnt]); 94 while(x!=y){ 95 if(dep[x]<dep[y])swap(x,y); 96 ins(cnt,id[x]),//printf("link:%d-->%d ",cnt,id[x]), 97 top[x]=gettop(FA[x][0]),x=top[x];//printf(" %d %d ",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 ",/*tmp*/_getmx(x,y)); 108 } 109 }