文章标题 HDU 2874 : Connections between cities(LCA+并查集)
来源:互联网 发布:淘宝买家怎么提升等级 编辑:程序博客网 时间:2024/06/08 14:21
题目链接
题意:有n个点组成的森林,然后有c个询问,每次询问u->v有没有一条路径,有的话,输出这条路径的距离,没有的话输出“Not connected”
分析:首先,判断是否有路径到达,只需要用并查集,看一下两个点是否在同一颗树上,然后对于有路径的两个点,我们可以求他们的LCA,然后通过dis[u]+dis[v]-2*dis[lca]来得到答案,但是题目给的是森林不是树,可以用另一个点作为树根,然后将森林中的每一颗树给连起来,这样就是一颗树了。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <queue>#include <set>#include <map>#include <algorithm>#include <math.h>#include <vector>using namespace std;typedef long long ll;const int mod=1e9+7;const int maxn=1e6+10;int n,m,c;int fa[maxn];//并查集 int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); }//建图 struct Edge{ int to,nex,val;}edge[maxn];int head[maxn],tot;void init(){ tot=0; memset (head,-1,sizeof (head));}void addedge(int u,int v,int w){ edge[tot]=Edge{v,head[u],w}; head[u]=tot++;} //lca.. int dis[maxn];//dis[i]表示节点i到树根的距离 int dp[maxn*2][20];int first[maxn];//first[i]表示i这个节点第一次出现的标号 int dep[maxn*2];//深度 int point[maxn*2];//point[i]表示标号为i所对应的节点 int vis[maxn];//标记节点是否被访问过了 int cnt;//遍历是节点的数目 void dfs(int u,int idx){//深搜 vis[u]=true; point[++cnt]=u; first[u]=cnt; dep[cnt]=idx; for (int i=head[u];i!=-1;i=edge[i].nex){ int v=edge[i].to; int w=edge[i].val; if (!vis[v]){ dis[v]=dis[u]+w; dfs(v,idx+1); point[++cnt]=u; dep[cnt]=idx; } }}void RMQ_init(int n){//预处理 for (int i=1;i<=n;i++)dp[i][0]=i; for (int k=1;(1<<k)<=n;k++){ for (int i=1;i+(1<<k)-1<=n;i++){ int a=dp[i][k-1]; int b=dp[i+(1<<(k-1))][k-1]; if (dep[a]>dep[b])dp[i][k]=b; else dp[i][k]=a; } }} int RMQ(int l,int r){//求最小值 int k=0; while ((1<<(k+1))<=r-l+1)k++; int a=dp[l][k]; int b=dp[r-(1<<k)+1][k]; return dep[a]>dep[b]?b:a;}int LCA(int u,int v){//求LCA int x=first[u],y=first[v]; if (x>y)swap(x,y); int ans=RMQ(x,y); return point[ans];}int main(){ while (scanf ("%d%d%d",&n,&m,&c)!=EOF){ int u,v,w; init(); for (int i=0;i<=n;i++)fa[i]=i; for (int i=0;i<m;i++){ scanf ("%d%d%d",&u,&v,&w); int fu=find(u),fv=find(v); if (fu!=fv){ fa[fu]=fv; } addedge(u,v,w); addedge(v,u,w); } for (int i=1;i<=n;i++){//以n+1为树根,将森林连成树 if (fa[i]==i){ addedge(n+1,i,0); addedge(i,n+1,0); } } memset (dis,0,sizeof (dis)); memset (dep,0,sizeof (dep)); memset (vis,0,sizeof (vis)); cnt=1; dfs(n+1,1); RMQ_init(cnt-1);//初始化RMQ while (c--){ scanf ("%d%d",&u,&v); int fu=find(u),fv=find(v); if (fu!=fv){ printf ("Not connected\n"); } else { int lca=LCA(u,v); ll ans=dis[u]+dis[v]-2*dis[lca]; printf ("%lld\n",ans); } } } return 0;}
阅读全文
0 0
- 文章标题 HDU 2874 : Connections between cities(LCA+并查集)
- hdu 2874 Connections between cities LCA || dfs+并查集
- |hdu 2874|LCA|并查集|Connections between cities
- HDU 2874 —— Connections between cities(并查集+LCA)
- hdu2874 Connections between cities(LCA离线+并查集)
- hdu 2874 Connections between cities (并查集+LCA)hash优化
- Connections between cities (hdu 2874 LCA)
- hdu 2874 Connections between cities(LCA)
- HDU 2874Connections between cities(LCA)
- HDOJ 题目2874 Connections between cities(LCA转RMQ+并查集)
- HDU2874 Connections between cities LCA+DFS或并查集
- HDU2874——Connections between cities 详解 (LCA,RMQ,数据结构,dfs序,并查集)
- hdu 2874 Connections between cities LCA
- HDU 2874 Connections between cities [LCA]
- hdu 2874 Connections between cities (LCA)
- hdu 2874 Connections between cities(LCA)
- 【HDU】2874 Connections between cities 离线LCA
- hdu 2874 Connections between cities(LCA)
- 机器学习---Logistic回归数学推导以及python实现
- 物联网思维详解
- 安装nagvis-1.9.2步骤
- iOS 单例设计模式
- 数据库报错无法打开的紧急救援案例
- 文章标题 HDU 2874 : Connections between cities(LCA+并查集)
- yum安装lnmp-mysql
- ImageLoader加载图片
- linux编程---线程---条件变量
- MapReduce 程序(1)
- 仪表盘类型
- python6-运用PIL模块的简单图像处理
- 什么时候要用存储过程
- C# 结束程序代码