计蒜客2019蓝桥杯国赛B组模拟赛题解汇总:
https://blog.csdn.net/daixinliangwyx/article/details/90231587
第五题
标题:蒜头图
解法:“蒜头图”其实也就是环,可以用并查集求图里面环的个数。在建图连边的过程中,在a和b两个点连边之前先判断一下这两个是否是一个块里面的:初始图里面的环数量为:sum-1;(sum=1)
如果是,则代表目前的图已经是存在环的,在目前的环里面又加了一条边,整个图的环数量变为sum*2-1(表现在代码里也就是sum*=2,在输出里面再减1)。由于这两个点已经联通,就可以不用再掉join来连通起来了,但实际上这两个点之间是又多了一条边的(表现在了图里环的数量变多)。
如果不是,则直接进行连边join(a, b)。
每一次判断完后输出当前图里环的数量:sum-1
如果又连边改变了整个图则继续进行上面的判断,sum的变化一直随着加边循环下去。
代码:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static InputReader in = new InputReader(new BufferedInputStream(System.in));
public static PrintWriter out = new PrintWriter(System.out);
public static int n, m, u, v;
public static int[] pre = new int[100010];
public static long ans, mod = 1046513837;
public static void main(String[] args) {
n = in.nextInt();
m = in.nextInt();
for (int i = 1; i <= n; i++)
pre[i] = i;
ans = 1;
while (m-- > 0) {
u = in.nextInt();
v = in.nextInt();
if (find(u) == find(v)) {
ans = (ans * 2) % mod;
} else {
join(u, v);
}
out.println((ans - 1) % mod);
out.flush();
}
out.close();
}
static int find(int x) {
if (x == pre[x]) return pre[x];
else
return pre[x] = find(pre[x]);
}
static void join(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
pre[fx] = fy;
}
}
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public String nextLine() {
String str = null;
try {
str = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public Double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}
}
评测结果: