A1. 道路修建 Small(BNUOJ)

A1. 道路修建 Small

Time Limit: 1000ms

Memory Limit: 131072KB

64-bit integer IO format: %lld      Java class name: Main

Submit Status

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

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


输入格式


操作说明


输出结果


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 }
时间: 2024-10-13 01:34:44

A1. 道路修建 Small(BNUOJ)的相关文章

【BZOJ-2435】道路修建 (树形DP?)DFS

2435: [Noi2011]道路修建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3115  Solved: 1002[Submit][Status][Discuss] Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿意修建恰好 n – 1条双向道路. 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家

bzoj2435[Noi2011]道路修建

bzoj2435[Noi2011]道路修建 题意: 给个n点树,每条边的费用为这条边两端的节点数的差值*这条边的长度,求这个数的总费用. 题解: 水题,dfs求出节点的子树大小sz,对于每一条边,费用为深度大的sz值与n-sz相减的绝对值乘边的长度. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i+

2435: [Noi2011]道路修建(求助!!!)

2435: [Noi2011]道路修建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2188  Solved: 639[Submit][Status] Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿意修建恰好 n – 1条双向道路. 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家个数之差的绝对值.例

【NOI2011】道路修建 BFS

[NOI2011]道路修建 Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿意修建恰好 n – 1条双向道路. 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家个数之差的绝对值.例如,在下图中,虚线所示道路两端分别有 2 个.4个国家,如果该道路长度为 1,则费用为1×|2 – 4|=2.图中圆圈里的数字表示国家的编号. 由于国家的数量十分庞大,道路的建

【BZOJ】【2435】【NOI2011】道路修建

DFS/DP 本来以为是一道傻逼题,然而跪了好久……一直RE…… 直接dfs就好了……x->y val=c  :  ans+=abs(n-size[y]-size[y])*c; 然而为啥会一直RE呢? 后来改成dfs返回当前节点的size就过了……过了…… 100W的节点难道linux下也会爆栈嘛= =?sad 1 /************************************************************** 2 Problem: 2435 3 User: Tun

2435: [Noi2011]道路修建 - BZOJ

Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿意修建恰好 n – 1条双向道路. 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家个数之差的绝对值.例如,在下图中,虚线所示道路两端分别有 2 个.4个国家,如果该道路长度为 1,则费用为1×|2 – 4|=2.图中圆圈里的数字表示国家的编号. 由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案

bzoj 2435: [Noi2011]道路修建 树上 dp

2435: [Noi2011]道路修建 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=2435 Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1条双向道路. 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘

NOIp2011道路修建

题目描述 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路. 每条道路的修建都要付出一定的费用,这个费用等于道路长度乘以道路两端 的国家个数之差的绝对值.例如,在下图中,虚线所示道路两端分别有 2 个.4 个国家,如果该道路长度为 1,则费用为 1×|2 – 4|=2.图中圆圈里的数字表示国 家的编号.  由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案

【BZOJ】2435: [Noi2011]道路修建(树形dp)

http://www.lydsy.com/JudgeOnline/problem.php?id=2435 我怎么感觉那么水.. 坑的是,dfs会爆...好吧..用bfs.. #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue&