zoukankan      html  css  js  c++  java
  • A1. 道路修建 Small(BNUOJ)

    A1. 道路修建 Small

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

    无向图G初始有n个点,从1n依次标号,但是没有边,

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

    输入格式

    操作说明

    输出结果

    0_u_v

    加入一条连接标号为u和标号为v的点的边。

    输出加边后图G中连通块的个数。

    1_u_v

    查询标号为u和标号为v的点之间是否连通。

    如果连通,输出k,表示最早在第k次操作后标号为u和标号为v的点之间连通,否则输出0

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

    Input

    第一行是一个正整数T(T leq 5),表示测试数据的组数,

    对于每组测试数据,

    第一行包含两个整数n(1 leq n leq 1000)m(0 leq m leq 5000)

    接下来m行,每行是3个整数puv,请注意所给的uv均是经过加密的,

    解密方式是u=u  xor  lastansv=v  xor  lastans ,其中lastans表示上一次操作的输出结果,

    初始lastans=0,保证p in {0,1},解密后1 leq u,v leq nu 
e v

    Output

    对于每组测试数据,

    输出m行,每行包含一个整数,表示操作的输出结果。

    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 ",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 ",cnt);
    116             }
    117             else if(s==1)
    118             {
    119                 printf("%d ",yy[p][q]);
    120                 nn=yy[p][q];
    121             }
    122         }
    123 
    124     }
    125     return 0;
    126 }
     
    油!油!you@
  • 相关阅读:
    springboot常见应用属性
    springboot日志
    springboot注解
    2018年5月26日笔记
    LAMP环境搭建与配置
    2018年5月24日笔记
    2018年5月22日笔记
    2018年5月19日笔记
    2018年5月17日笔记
    2018年5月15日笔记
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5180608.html
Copyright © 2011-2022 走看看