[2017纪中11-9]玩游戏 最短路数+LCA 4000
2017-11-10 15:39
197 查看
题面
考虑这样定义的最短路对应的最短路树恰好是最小生成树。因为add操作不多,每次暴力重构最短路树,询问的时候跑lca即可。复杂度O(n^2logn)。
代码:
考虑这样定义的最短路对应的最短路树恰好是最小生成树。因为add操作不多,每次暴力重构最短路树,询问的时候跑lca即可。复杂度O(n^2logn)。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define ll long long using namespace std; int n,m,K,Q,fa[5010],d[5010],f[5010][15]; ll g[5010][15]; struct edge { int t;ll w; edge *next; }*con[5010]; void ins(int x,int y,ll w) { edge *p=new edge; p->t=y; p->w=w; p->next=con[x]; con[x]=p; } struct node { int x,y;ll w; }e[110000],z[5010]; bool cmp(node a,node b){return a.w<b.w;} int getfa(int v) { if(fa[v]==v) return v; fa[v]=getfa(fa[v]); return fa[v]; } bool merge(int x,int y) { if(getfa(x)!=getfa(y)) {fa[fa[x]]=y;return 1;} return 0; } void MST(int &m) { for(int i=1;i<=n;i++) fa[i]=i; sort(e+1,e+m+1,cmp); int cnt=0; for(int i=1;i<=m;i++) { if(merge(e[i].x,e[i].y)) z[++cnt]=e[i]; if(cnt==n-1) break; } for(int i=1;i<n;i++) e[i]=z[i]; m=n-1; } void dfs(int v) { d[v]=d[f[v][0]]+1; for(edge *p=con[v];p;p=p->next) if(p->t!=f[v][0]) { f[p->t][0]=v; g[p->t][0]=p->w; dfs(p->t); } } void pre() { for(int k=1;(1<<k)<=n;k++) for(int i=1;i<=n;i++) f[i][k]=f[f[i][k-1]][k-1],g[i][k]=max(g[i][k-1],g[f[i][k-1]][k-1]); } ll qry(int x,int y) { ll re=0; if(d[x]<d[y]) swap(x,y); for(int k=14;k>=0;k--) if(d[f[x][k]]>=d[y]) re=max(re,g[x][k]),x=f[x][k]; if(x==y) return re; for(int k=14;k>=0;k--) if(f[x][k]!=f[y][k]) re=max(re,max(g[x][k],g[y][k])),x=f[x][k],y=f[y][k]; return max(re,max(g[x][0],g[y][0])); } int main() { scanf("%d%d%d",&n,&m,&K); for(int i=1;i<=m;i++) scanf("%d%d%lld",&e[i].x,&e[i].y,&e[i].w); scanf("%d",&Q); bool mi=1; while(Q--) { char opt[6];int x,y;scanf("%s",opt); if(opt[0]=='g') { if(mi) { MST(m); for(int i=1;i<=n;i++)con[i]=NULL; memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); memset(d,0,sizeof(d)); for(int i=1;i<=m;i++) ins(e[i].x,e[i].y,e[i].w),ins(e[i].y,e[i].x,e[i].w); dfs(1); pre(); mi=0; } ll ans=0; for(int i=1;i<=K;i++) { scanf("%d%d",&x,&y); ans^=qry(x,y); } if(ans==0) puts("Baozika"); else puts("madoka"); } else {m++;mi=1;scanf("%d%d%lld",&e[m].x,&e[m].y,&e[m].w);} } return 0; }
相关文章推荐
- 例题11-11 赛车比赛 单源最短路 spfa
- [2017纪中11-4][Codeforces Round #395 Div.1]C pacifist
- [2017纪中11-2]字典序 拓扑排序+优先队列
- [2017纪中11-6]拆网线 树型DP/二分图匹配
- [2017纪中11-4][ARC071]F-neutral DP
- [2017纪中11-2]救赎 dfs序+树状数组 / 递推
- [2017纪中11-5]轰炸 强联通分量+DAG最长路
- [2017纪中11-2]失格 最小生成树+数论
- [2017纪中11-3][ARC069-F]高考是不可能高考的 2-sat+线段树优化建图
- [2017纪中11-5]好路线 DP
- [2017纪中11-6]奇怪的队列 树状数组+二分/线段树
- [2017纪中11-8]购物 贪心+优先队列
- [2017纪中11-3]机房比教室好多了 博弈+树型DP
- [2017纪中11-5]仔细的检查 树hash
- [2017纪中11-8]好文章 字符串hash+STL
- 小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和
- [2017纪中11-9]乘积 数论+分组背包
- 最短路经典例题-紫书11-4 Calling Circles(Floyd传递闭包+map+DFS)
- [2017纪中11-1]背包 二分
- [2017纪中11-9]道路重建 点双连通分量+树的直径