之江学院第0届校赛-H.qwb与学姐(最大生成树+lca)
来源:互联网 发布:win10网络允许 编辑:程序博客网 时间:2024/04/30 19:40
记录一个菜逼的成长。。
题目链接
一开始看到这题,想的是最大生成树+树链剖分+线段树。时间复杂度大概是
然而貌似是因为线段树的常数大然后炸了。。(不会zkw线段树,待学。orz
然后题解说的是最大生成树+倍增法lca
就是创建一个数组
然后跟
#include <bits/stdc++.h>using namespace std;#define ALL(v) (v).begin(),(v).end()#define cl(a,b) memset(a,b,sizeof(a))#define clr clear()#define pb push_back#define mp make_pair#define fi first#define se second#define lson t<<1,l,mid#define rson t<<1|1,mid+1,rconst int INF = 0x3f3f3f3f;typedef long long LL;typedef pair<int,int> PII;const int maxe = 200000 + 10;const int maxn = 100000 + 10;struct Edge{ int to,next,w;}edge[maxn];int head[maxn],cnt;int deep[maxn],anc[maxn][20];int n,m;int dis[maxn][20];void add(int u,int v,int w){ edge[cnt].to = v; edge[cnt].next = head[u]; edge[cnt].w = w; head[u] = cnt++;}void init(){ cl(head,-1); cl(deep,0); cl(anc,-1); cl(dis,INF); cnt = 0;}void dfs(int u,int pre,int d){ deep[u] = d; for( int i = head[u]; ~i; i = edge[i].next ){ int v = edge[i].to; if(v == pre)continue; anc[v][0] = u; dis[v][0] = edge[i].w; dfs(v,u,d+1); }}void Init(){ for( int j = 1; (1<<j) <= n; j++ ){ for( int i = 1; i <= n; i++ ){ if(anc[i][j-1] != -1){ anc[i][j] = anc[anc[i][j-1]][j-1]; dis[i][j] = min(dis[i][j-1],dis[anc[i][j-1]][j-1]); } } }}int lca(int a,int b){ int ret = INF; int i,j; if(deep[a] < deep[b])swap(a,b); for( i = 0; (1<<i) <= deep[a]; i++ ); i--; for( j = i; j >= 0; j-- ){ if(deep[a] - (1<<j) >= deep[b]){ ret = min(ret,dis[a][j]); a = anc[a][j]; } } if(a == b)return ret; for( j = i; j >= 0; j-- ){ if(anc[a][j] != -1 && anc[a][j] != anc[b][j]){ ret = min(ret,dis[a][j]); ret = min(ret,dis[b][j]); a = anc[a][j]; b = anc[b][j]; } } ret = min(ret,dis[a][0]); ret = min(ret,dis[b][0]); return ret;}int pre[maxn],ra[maxn];struct Bian{ int u,v,d; Bian(){} Bian(int uu,int vv,int dd){ u = uu; v = vv; d = dd; }}bian[maxe];bool cmp(Bian a,Bian b){ return a.d > b.d;}int findr(int x){ return pre[x] == x ? pre[x] : pre[x] = findr(pre[x]);}void Kruskal(int n,int m){ for( int i = 1; i <= n; i++ )pre[i] = i; sort(bian,bian+m,cmp); for( int i = 0; i < m; i++ ){ int u = findr(bian[i].u),v = findr(bian[i].v); if(u == v)continue; pre[u] = v; add(bian[i].u,bian[i].v,bian[i].d); add(bian[i].v,bian[i].u,bian[i].d); }}int main(){ int k; while(~scanf("%d%d%d",&n,&m,&k)){ init(); for( int i = 0; i < m; i++ ){ scanf("%d%d%d",&bian[i].u,&bian[i].v,&bian[i].d); } Kruskal(n,m); dfs(1,1,0); Init(); while(k--){ int x,y; scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } } return 0;}
阅读全文
0 0
- 之江学院第0届校赛-H.qwb与学姐(最大生成树+lca)
- qwb与学姐---之江学院第0届校赛最大生成树+lca
- 之江学院第0届校赛 Problem H: qwb与学姐(最大生成树+树链剖分)
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛 H: qwb与学姐 [MST+LCA]【数据结构】
- 之江学院校赛 qwb与学姐 最大生成树+LCA
- 之江学院第0届校赛(决赛) qwb与支教 (二分+容斥原理)
- 之江学院第0届校赛决赛 A-qwb与支教(容斥+二分)
- 之江学院第0届校赛决赛 K-qwb与小数
- qwb 与学姐 lca+mst
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛 B: qwb与矩阵
- 浙江工业大学之江学院2017年第0届达内杯A题——qwb与支教
- 之江学院第0届网络邀请赛 qwb与矩阵
- 之江学院第0届校赛 Problem I: qwb VS 去污棒(可持久化01字典树)
- 之江学院第0届校赛决赛 F-qwb has a lot of Coins
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛 D.qwb与神奇的序列【递推】
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛—B qwb与矩阵
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛—D qwb与神奇的序列
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛—K qwb与小数
- a= b?c:d 问号表达式
- 统计自然语言处理(概率上下文无关文法)
- HTML5仿手机微信聊天界面
- 61 用C语言写一个内存溢出的例子
- bdd logo位置
- 之江学院第0届校赛-H.qwb与学姐(最大生成树+lca)
- Linux学习进阶路线图
- 多线程-线程的状态转换图及常见执行情况
- 利用core文件对多线程和多进程进行调试
- ★★★★★IP分片的原因、原理、实现以及引起的安全问题
- padding,margin带一个、二个、三个、四个参数的不同含义
- 14_运算符_02_字符串连接_三元运算符_优先级问题
- 62 C语言数组的概念
- 微服务实战(四):服务发现的可行方案以及实践案例