题目描述

最近,木木中学要举行一年一度的辩论赛了,我们活泼开朗乐观向上不寂寞不生病不挂科天天回家吃饭的新时代好少年--飞飞,自然是热情参与咯!辩论嘛,就有正方和反方两个组,这是一个传统项目,所以,包括飞飞,木木中学的每一个学生都会加入2个组中的一个,不会有人打酱油的(如果有人打酱油,那么飞飞会义无反顾义不容辞的上前用一翻惊天动地的演说打消他打酱油的念头的)。自然啦,作为有思想有文化能言善辩的好少年,飞飞,其实加入哪个组,从技术角度分析真是无所谓的,不过呢,从另外一些角度来看,就复杂的多了……比如,飞飞是个很不喜欢八卦的正义青年,所以啊,飞飞很不想和年级最PP的女生青菜分在一个组,因为会产生八卦的--为什么会有八卦?首先是他们比较熟(比较熟就会有八卦吗?无限yy中……),最重要的就是因为飞飞是大帅哥啊!人长得帅,有时候真是挺麻烦的,尤其飞飞还如此低调……再比如,飞飞也不想和小邱分在一个组--虽然他们不认识,但是,飞飞听说小邱很懒还很暴力,飞飞不喜欢暴力……当然了,不论如何的分组行动,都会产生一些代价的,比如两个好朋友分在了不同的组,那肯定不是很高兴了。飞飞知道,学校里有M对同学是相互认识的,每对认识的同学间,都有一个要好程度C,自然的,关系越好,要好程度越高,也越不愿意分开。对于一个分组方案,必然会使得有某些认识的同学分开,飞飞认为,一个分组方案的代价就是最不愿意分开的那两个同学之间的要好程度。飞飞在想,和青菜MM分在不同的组最小代价是多少呢?和小邱同学分在不同的组最小代价是多少呢?如果……还要将青菜MM和小邱分在不同的组最小代价是多少呢?……好麻烦啊,飞飞越想越乱,于是来找你帮忙了。一些说明:木木中学有N个学生,木木中学是一所优秀的中学,学生们都是开朗外向的,所以一个学校里任意两个学生间接或者直接肯定认识。显然任意一个辩论组都至少得有一个人。为了方便,我们把木木中学的学生用1到N编号,飞飞有Q个问题,每个问题的形式都是这样的:将编号为a的学生与编号为b的学生分在不同组中,最少的代价是多少呢?关于这道题目本身,只是想检验你能不能帮飞飞,所以你并不需要--具体回答每个问题,只需要最后输出每个问题答案的乘积除以P的余数就可以了。

输入格式

输入文件中的第一行为四个正整数N,M,Q,P。

第二行至第M+1行,每行有三个正整数a,b,c,表示编号为a的同学和编号为b的同学认识,并且要好程度是c。

保证a和b是不会相同的,也不会有多行描述相同两个学生之间的关系。

第M+2行至第M+Q+1行,每行有两个正整数a,b,表示飞飞的一个问题,这里保证a和b是不同的。

N<5000,M<10000,Q<1000,C<1000000,P<1000000。

输出格式

输出文件中仅一行为一个整数,所有问题答案的乘积除以P的余数。


题目翻译过来就是:对于每个询问的a,b,要求将原图分成两个不相连的连通块,并且a,b不在同一个连通块中,答案就是原图中两个连通块之间相连的边的边权最大值。

进一步,我们可以把题目理解为:删掉一些边使得a,b不连通,删去边的最大值就是答案。

但是删边的操作太复杂,不如考虑倒过来变成加边的操作。

显然删边时我们需要从小到大删,那么加边时我们就从大到小加。然后当加上一条边使得a,b连通时,此时加的边的边权就是答案,因为比这条边更大的边不足以使a,b连通,那么我们可以把它们放入连通块中。而此时剩下的边不会大于当前边,无论删哪些边答案都是当前边的边权。

考虑实现方式:

先对边从大到小排序。加边可以用并查集实现,每次加边之后枚举每个询问,看是否未被回答过并且现在连通了,并记录答案。忽略掉并查集的复杂度,那么时间复杂度就是O(MlogM+MQ),会T掉。那么考虑优化:

我们的原本的策略是回答一个询问后打上标记,当再次循环到这个位置时就跳过。那么当询问回答得差不多时就会产生很大的空转。那么我们的优化方法有两个:

1.Dancing Links,用链表的形式存储询问,回答了当前询问时就从链表删掉这个询问。

2.队列优化。将未回答的询问加入队列,回答之后将询问出队。

那么用了上述优化之后可以把复杂度降为O(MlogM+KQ),K是一个比较小的常数。


但上面的离线做法显然不尽人意,原因是处理问题时不能及时调动存储的询问。所以我们可以考虑在线做法。

类比着离线做法,用并查集从大到小加边可以看作是求原图的最大生成树,加到询问的两个点连通的边可以看作是询问的两点在最大生成树的路径上的最小边。所以我们在线的做法就是:

求出最大生成树,然后对于每个询问,求出两点在树上路径上的最小边,这个可以用倍增求。那么复杂度就是:O(MlogM+(N+Q)logN)

放出在线做法的代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define maxn 5001
#define maxm 10001
using namespace std; int n,m,q,p,ans=1;
inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
} struct edge{
int to,dis,next;
edge(){}
edge(const int &_to,const int &_dis,const int &_next){ to=_to,dis=_dis,next=_next; }
}e[maxn<<1];
int head[maxn],k;
inline void add(const int &u,const int &v,const int &w){ e[k]=edge(v,w,head[u]),head[u]=k++; } struct birm{
int u,v,w;
bool operator<(const birm &b)const{ return w>b.w; }
}b[maxm];
int fa[maxn],tot;
int get(int x){ return x==fa[x]?x:fa[x]=get(fa[x]); }
inline void kruskal(){
sort(b+1,b+1+m);
for(register int i=1;i<=n;i++) fa[i]=i;
for(register int i=1;i<=m;i++){
int u=b[i].u,v=b[i].v,w=b[i].w;
if(get(u)==get(v)) continue;
fa[get(u)]=get(v),tot+=w;
add(u,v,w),add(v,u,w);
}
} int minedge[maxn][20],f[maxn][20],dep[maxn],maxdep;
void dfs_getmax(int u,int pre){
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==pre) continue;
f[v][0]=u,minedge[v][0]=e[i].dis,dep[v]=dep[u]+1;
for(register int j=1;j<=maxdep;j++) f[v][j]=f[f[v][j-1]][j-1],minedge[v][j]=min(minedge[v][j-1],minedge[f[v][j-1]][j-1]);
dfs_getmax(v,u);
}
}
inline int getmin(int u,int v){
int ans=0x3f3f3f3f;
if(dep[u]>dep[v]) swap(u,v);
for(register int i=maxdep;i>=0;i--) if(dep[f[v][i]]>=dep[u]) ans=min(ans,minedge[v][i]),v=f[v][i];
if(u==v) return ans;
for(register int i=maxdep;i>=0;i--) if(f[u][i]!=f[v][i]) ans=min(ans,min(minedge[u][i],minedge[v][i])),u=f[u][i],v=f[v][i];
return min(ans,min(minedge[u][0],minedge[v][0]));
} int main(){
memset(head,-1,sizeof head),memset(minedge,0x3f,sizeof minedge);
n=read(),m=read(),q=read(),p=read(),maxdep=(int)log(n)/log(2)+1;
for(register int i=1;i<=m;i++) b[i].u=read(),b[i].v=read(),b[i].w=read();
kruskal(),dfs_getmax(1,-1);
for(register int i=1;i<=q;i++){
int u=read(),v=read();
ans=(1ll*ans*getmin(u,v))%p;
}
printf("%d\n",ans);
return 0;
}

[noip模拟]分组行动的更多相关文章

  1. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  2. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  3. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  4. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  5. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  6. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  7. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  8. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  9. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

随机推荐

  1. css 08-CSS属性:定位属性

    08-CSS属性:定位属性 CSS的定位属性有三种,分别是绝对定位.相对定位.固定定位. position: absolute; <!-- 绝对定位 --> position: relat ...

  2. 回文数字(Palindrome Number)

    总时间限制:1000ms 内存限制: 65536kB 描述 给出一系列非负整数,判断是否是一个回文数.回文数指的是正着写和倒着写相等的数. 输入 一行,一个01字符串. 输出 若干行,每行是一个非负整 ...

  3. Wordpress Polylang 翻译自定义格式

    WordPress 多语言插件 Polylang 主题函数参考 重要:使用一个函数之前,你必须检查函数是否存在,否则,你的网站可能会在 Polylang 更新之前遇到致命错误(因为 WordPress ...

  4. 【超详细】MakeDown(Typora)+PicGo+Gitee实现图床

    [超详细]MakeDown(Typora)+PicGo+Gitee实现图床 序言:我们有时在用makedown整理笔记时想把自己的笔记上传到博客园,可是发现在上传过程中makedown中的图片显示不出 ...

  5. 我们是如何实现DevOps的

    一.DevOps的理解 DevOps的概念理解 DevOps 的概念在软件开发行业中逐渐流行起来.越来越多的团队希望实现产品的敏捷开发,DevOps 使一切成为可能.有了 DevOps ,团队可以定期 ...

  6. PPT技术干货1(上)——设计审美

    序言 PPT直接反映了一个人的能力和态度,PPT能直接反映出老板最看重的4个关键能力: 逻辑思维:全局思考,洞察关键 数据思维:数据分析,指导决策 设计思维:美观大方,彰显专业 工作效率:效率高,出活 ...

  7. 前端可视化开发--liveload

    在前端开发中,我们会频繁的修改html.css.js,然后刷新页面,开效果,再调整,再刷新,不知不觉会浪费掉我们很多时间.有没有什么方法,我在编辑器里面改了代码以后,只要保存,浏览器就能实时刷新.经过 ...

  8. Spring Boot 使用常见问题

    Json格式化时间,时区设置 spring.jackson.time-zone=GMT+8 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss json数据无 ...

  9. POLARDB与其他关系型数据库对比

    https://baijiahao.baidu.com/s?id=1610828839695075926&wfr=spider&for=pc 前言 在数据库的选择上,MySQL成为中国 ...

  10. Spring 抽象的缓存包 spring-cache

    项目实战 用户信息查询接口中,使用@Cacheable注解  绑定相关信息接口中,使用@CachePut更新用户信息到缓存 更新用户信息接口中,使用@CacheEvict删除缓存信息 使用步骤 添加依 ...