NOIP2013提高组Day1
来源:互联网 发布:商品sku数据库设计 编辑:程序博客网 时间:2024/06/05 14:03
NOIP2013Day1
一、转圈游戏
按照题意每个人往后m个,那就是(10^k*m+x)%n,然后用快速幂就可以了
二、火柴排队
看起来很像鬼脚图,但是有点不一样,鬼脚图的上一层是固定的,但这里两层都可以动
注意到交换对于交换上面还是交换下面效果都是一样的,那么直交换下面就可以了
这样和鬼脚图就一模一样了,排序一下,重新定义一下就行了
三、货车运输
我一档档写了过来
对于30分,和七夕是一样的,只要枚举每条边作为最小的那个限重,然后判连通,不断更新即可
对于60分,修改一下上面的,对于每一个询问,二分限重来求所需的限重。限重满足线形,越小越容易实现
对于100分,是最大生成树+倍增+LCA。注意到要使每一条路径都最长,那么短的路径就可以舍去了
用倍增和LCA求两点在树上的路径上的最小权值即可
注意这可能是森林而不是一个完整的树。我把每棵树都标上了颜色来区分。如果两点的颜色不同
那么他们所在的子树也不同,就无法连通,直接输出-1即可
Code:
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;int n,m,q;struct node{int x,y,z;}G[50005];bool cmp(node x,node y){return x.z>y.z;}struct node1{int to,v;};vector<node1>edge[10005];struct Tree1{//造出最大生成树 int fa[10005]; int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);} void solve(){ for(int i=1;i<=n;i++)fa[i]=i; sort(G+1,G+1+m,cmp); for(int i=1;i<=m;i++){ int x=Find(G[i].x),y=Find(G[i].y); if(x==y)continue; edge[G[i].x].push_back((node1){G[i].y,G[i].z}); edge[G[i].y].push_back((node1){G[i].x,G[i].z}); fa[x]=y; } }}Tree;int fa[17][10005],dep[10005],dis[17][10005],co[10005],col;struct Init1{//预处理倍增的东西 bool Q[10005]; void f(int x,int fa1){ dep[x]=dep[fa1]+1;fa[0][x]=fa1;Q[x]=1;co[x]=col; for(int i=0;i<(int)edge[x].size();i++){ int y=edge[x][i].to,v=edge[x][i].v; if(fa1==y)continue; dis[0][y]=v; f(y,x); } } void Init(){//倍增 for(int j=1;j<17;j++) for(int i=1;i<=n;i++){ fa[j][i]=fa[j-1][fa[j-1][i]]; dis[j][i]=min(dis[j-1][i],dis[j-1][fa[j-1][i]]); } } void solve(){ col=1; for(int i=1;i<=n;i++)if(Q[i]==0)f(i,0),col++; Init(); }}Init;int LCA(int x,int y){//LCA if(dep[x]>dep[y])swap(x,y); int step=dep[y]-dep[x]; for(int i=0;i<17;i++) if(step&(1<<i))y=fa[i][y]; if(x==y)return x; for(int i=16;i>=0;i--) if(fa[i][x]!=fa[i][y]) x=fa[i][x],y=fa[i][y]; return fa[0][x];}int work(int x,int y){//跳着向上 int step=dep[x]-dep[y],mn=1e9; for(int i=16;i>=0;i--) if(step&(1<<i)) mn=min(mn,dis[i][x]),x=fa[i][x]; return mn;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)scanf("%d%d%d",&G[i].x,&G[i].y,&G[i].z); Tree.solve();//建树 Init.solve();//倍增 scanf("%d",&q); for(int i=1;i<=q;i++){//每个点的询问 int x,y; scanf("%d%d",&x,&y); if(co[x]!=co[y])puts("-1"); else{ int lca=LCA(x,y); int L=work(x,lca),R=work(y,lca); printf("%d\n",min(L,R)); } } return 0;}
一次最简单的考试。一半的人AK了。所以也不想写了。
阅读全文
0 0
- NOIP2013提高组Day1
- 【NOIP2013】【提高组】【Day1】【解题报告】
- 【NOIP2013提高组day1】火柴排队
- 7.11 noip2013提高组复赛day1
- NOIP2013提高组Day1 解题报告
- NOIP2013 提高组 复赛 day1 circle 转圈游戏
- noip2013提高组【Day1】·转圈游戏·题解+【快速幂】
- 2016.7.12 NOIP2013提高组day1解题报告(未完成版)
- NOIP2013复赛提高组day1(A:转圈游戏 B:火柴排队 C:货车运输)
- 【NOIP2013】day1
- NOIP2013 Day1
- NOIP2013提高组初赛
- 【NOIP2013提高组】花匠
- 【NOIP2013提高组】华容道
- 花匠【NOIP2013提高组】
- 【NOIP2013提高组】花匠
- NOIP2013提高组解析
- 【NOIP2013提高组】花匠
- 员工是公司最大的投资人
- Quartz快速入门指导
- 常用Mysql命令
- html重写搜索框的按钮
- Python备忘【1】输出0~255之间整数对应的二进制、八进制、十六进制数(填充对齐)
- NOIP2013提高组Day1
- AndroidStudio使用
- 进程学习:进程间通信(传统通信方式)1.无名管道
- tomcat启动脚本
- 六级_第十二天
- 关于Python写一个简单的验证码图片
- 代理模式
- hadoop 上传文件到HDFS报错
- 9.2 mnist_with_summaries tensorboard 可视化展示