A1. 道路修建 Small(BNUOJ)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A1. 道路修建 Small(BNUOJ)相关的知识,希望对你有一定的参考价值。

A1. 道路修建 Small

Time Limit: 1000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld      Java class name: Main

无向图技术分享初始有技术分享个点,从技术分享技术分享依次标号,但是没有边,

接下来有技术分享次操作,从技术分享技术分享依次标号,你需要对每种操作输出相应的结果,操作分为两种:

输入格式

操作说明

输出结果

0_u_v

加入一条连接标号为技术分享和标号为技术分享的点的边。

输出加边后图技术分享中连通块的个数。

1_u_v

查询标号为技术分享和标号为技术分享的点之间是否连通。

如果连通,输出技术分享,表示最早在第技术分享次操作后标号为技术分享和标号为技术分享的点之间连通,否则输出技术分享

(输入格式中的下划线‘_’表示实际输入文件中的空格)

Input

第一行是一个正整数技术分享,表示测试数据的组数,

对于每组测试数据,

第一行包含两个整数技术分享技术分享

接下来技术分享行,每行是技术分享个整数技术分享技术分享技术分享,请注意所给的技术分享技术分享均是经过加密的,

解密方式是技术分享技术分享 ,其中技术分享表示上一次操作的输出结果,

初始技术分享,保证技术分享,解密后技术分享技术分享

Output

对于每组测试数据,

输出技术分享行,每行包含一个整数,表示操作的输出结果。

Sample Input

1 4 7 0 1 2 1 1 0 0 1 3 0 0 1 1 0 1 0 1 7 1 0 5

Sample Output

3 0 2 2 3 1 6
思路:并查级。
用并查集判断有几个联通块。然后每次加点的时候将不同的两个集合合并到一起时,每个集合里的点相连通的时间最早时间就是此时合并的时间,开个yy数组记录就行了。
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 #include<math.h>
  6 #include<iostream>
  7 #include<vector>
  8 #include<cstdio>
  9 #define sc(x) scanf("%I64d",&x)
 10 #define pr(x) printf("%I64d",x)
 11 #define prr(x) printf(" %I64d",x)
 12 #define prrr(x) printf("%I64d\n",x)
 13 typedef long long ll;
 14 const ll N=1e9+7;
 15 using namespace std ;
 16 vector<int>aa[1005];//记录集合中的点
 17 int bb[10005];
 18 int dd[10005];
 19 int cc[10005];//并差集权重数组
 20 int gg[10005];
 21 int yy[1005][1005];//记录最早联通的时间
 22 int main(void)
 23 {
 24     int i,j,k,p,q,n,m,s;
 25     scanf("%d",&k);
 26     while(k--)
 27     {
 28         for(i=0; i<1005; i++)
 29         {
 30             aa[i].clear();
 31             aa[i].push_back(i);//先将自己加入集合
 32             bb[i]=i;
 33             cc[i]=1;
 34         }
 35         scanf("%d %d",&n,&m);
 36         memset(yy,0,sizeof(yy));
 37         int nn=0;//初始化输出
 38         int ans=0;
 39         for(i=1; i<=m; i++)
 40         {
 41             scanf("%d %d %d",&s,&p,&q);
 42             p=p^nn;
 43             q=q^nn;
 44             if(s==0)
 45             {
 46                 int x,y;
 47                 for(x=p; bb[x]!=x;)
 48                 {
 49                     x=bb[x];
 50                 }
 51                 for(y=q; bb[y]!=y;)
 52                 {
 53                     y=bb[y];
 54                 }
 55                 if(x!=y)
 56                 {
 57                     yy[p][q]=i;
 58                     yy[q][p]=i;
 59 
 60                     for(j=0; j<aa[x].size(); j++)
 61                     {
 62                         for(int  r=0; r<aa[y].size(); r++)
 63                         {
 64                             yy[aa[x][j]][aa[y][r]]=yy[aa[y][r]][aa[x][j]]=i;
 65 
 66                         }
 67                     }//记录联通最早的时间,因为他们在此时刚和并
 68                     yy[x][y]=i;
 69                     yy[y][x]=i;
 70                     if(cc[x]>cc[y])//合并集合
 71                     {
 72                         cc[x]+=cc[y];
 73                         bb[y]=x;
 74                         for(j=0; j<aa[y].size(); j++)
 75                         {
 76                             aa[x].push_back(aa[y][j]);
 77                         }
 78                         aa[x].push_back(y);
 79                         aa[y].clear();
 80 
 81                     }
 82                     else
 83                     {
 84                         cc[y]+=cc[x];
 85                         bb[x]=y;
 86                         for(j=0; j<aa[x].size(); j++)
 87                         {
 88                             aa[y].push_back(aa[x][j]);
 89                         }
 90                         aa[y].push_back(x);
 91                         aa[x].clear();
 92 
 93                     }
 94                 }
 95                 int gh;
 96                 for(int w=1; w<=n; w++)
 97                 {
 98                     for( gh=w; bb[gh]!=gh;)
 99                     {
100                         gh=bb[gh];
101                     }
102                     gg[w]=gh;
103                 }
104                 sort(gg+1,gg+1+n);//判断联通段
105                 int cnt=1;
106                 for(int h=2; h<=n; h++)
107                 {
108                     if(gg[h]!=gg[h-1])
109                     {
110                         cnt++;
111                     }
112                 }
113 
114                 nn=cnt;
115                 printf("%d\n",cnt);
116             }
117             else if(s==1)
118             {
119                 printf("%d\n",yy[p][q]);
120                 nn=yy[p][q];
121             }
122         }
123 
124     }
125     return 0;
126 }

 

 

以上是关于A1. 道路修建 Small(BNUOJ)的主要内容,如果未能解决你的问题,请参考以下文章

C1. 组队活动 Small(BNUOJ)

2435: [Noi2011]道路修建(树上操作)

洛谷P2052 道路修建

NOI2011道路修建 BFS

图论 洛谷P2052 道路修建

NOIp2011道路修建