LA3027合作网络

来源:互联网 发布:恒智天成软件 编辑:程序博客网 时间:2024/05/16 01:02

有N个结点

一次 I u v 操作表示把结点u的父结点设为v,距离为|u-v|%1000.输入保证执行指令前u没有父结点

一次E u 操作表示询问u到根结点的距离

O操作表示结束


解题思路:

因为题目只查询结点到根结点的距离,所以每棵树除了根结点不能换之外,其他结点的位置可以任意改变,,这恰好符合并查集的特点,但是需要记录附加信息。如果记录每个结点到根的距离,那么每次I操作都要更新很多结点的信息,时间复杂度难以保证,因此考虑记下每个结点到父结点的距离为d[i],然后在路径压缩时维护这个d数组,即到根结点的距离等于各枝距离之和。因为合并操作指定了父结点和子结点,所以不能使用启发式合并

完整代码如下

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>using namespace std;#define MAXSIZE 20010int par[MAXSIZE];int depth[MAXSIZE];int u,v;void Init(){  int i;  for(i=0;i<MAXSIZE;i++)  {    par[i]=i;depth[i]=0;  }}void InsertNode(){  par[u]=v;  depth[u]=abs(v-u);}int QueryNode(){  int ret=0;  while(par[u]!=u)  {ret+=depth[u];    u=par[u];  }return ret; }int main(){  int T;  int i;  cin>>T;  while(T--)  {    int n;char cmd[10];cin>>n;Init();for(i=0;i<n;i++){  cin>>cmd;  if(cmd[0]=='O')  {        break;  }  else if(cmd[0]=='I')  {cin>>u>>v;    InsertNode();  }  else if(cmd[0]=='E')      {cin>>u;    cout<<QueryNode()<<endl;    }}  }  return 0;}


0 0
原创粉丝点击