zoukankan      html  css  js  c++  java
  • 【2020去世模拟赛2】Freda的迷宫

    题目描述

    Freda是一个迷宫爱好者,她利用业余时间建造了许多迷宫。每个迷宫都是由若干房间和走廊构成的,每条走廊都连接着两个不同的房间,两个房间之间最多只有一条走廊直接相连,走廊都是双向通过。
    黄昏时候,Freda喜欢在迷宫当中漫步。每天,Resodo都会为Freda设计一个挑战方案。Resodo会指定起点和终点,请Freda来找到一条从起点到终点的简单路径。一条简单路径定义为一个房间序列,每个房间至多在序列里出现一次,且序列中相邻的两个房间有走廊相连。当起点和终点之间存在且仅存在一条简单路径的时候,Freda认为这个挑战方案是RD的。现在,请你帮帮Resodo来写一个程序,判断一个挑战方案是否是RD的。

    输入格式

    第一行三个整数N,M,Q.分别表示房间数,走廊数,询问数。
    接下来M行每行2个整数x,y, 0<x,y<=N, 表示x和y之间有一条走廊相连。
    接下来Q行每行2个整数x,y, 表示询问以x为起点,y为终点的挑战方案是否是RD的.
    输出格式
    对于每个询问,输出一行”Y”或者”N”(不含引号).Y表示该询问所表示的挑战方案是RD的,N表示该询问所表示的挑战方案不是RD的.

    样例输入

    6 5 3
    1 2
    2 3
    2 4
    2 5
    4 5
    1 3
    1 5
    2 6
    

    样例输出

    Y
    N
    N
    

    样例解释

    1,3之间只有一条路径 1->2->3
    1,5之间有两条路径 1->2->5 ; 1->2->4->5
    1,6之间没有路径

    数据范围与约定

    对于30%的数据,N<=100, M<=1000, Q<=100.
    对于50%的数据,N<=1000, M<=10000, Q<=1000.
    对于100%的数据,N<=10000, M<=100000, Q<=10000.

    Solution

    感觉好久没写割边系列的题了,现在板子都不会打了。(我好菜啊

    我们发现如果连接\(u\)\(v\)的简单路径上的边不是桥的话,就一定会有另外的路径也可以联通\(u\)\(v\)

    我们求出所有的桥,并将联通的桥所涉及的点做一个并查集。最后就可以直接查询了。

    #include <queue>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    
    const int N = 10002, M = 100002;
    
    int f[N], tot, dfn[N], low[N], cnt, n, m, Q, head[N], dot[M << 1], nxt[M << 1];
    
    int read() {
    	int x = 0, f = 1; char S;
    	while((S = getchar()) > '9' || S < '0') {
    		if(S == '-') f = -1;
    		if(S == EOF) exit(0);
    	}
    	while(S <= '9' && S >= '0') {
    		x = (x << 1) + (x << 3) + (S ^ 48);
    		S = getchar();
    	}
    	return x * f;
    }
    
    void addEdge(const int u, const int v) {
        dot[++ cnt] = v;
        nxt[cnt] = head[u];
        head[u] = cnt;
    }
    
    int findSet(const int x) {
        return x == f[x] ? x : f[x] = findSet(f[x]);
    }
    
    void unionSet(const int u, const int v) {
        int x = findSet(u), y = findSet(v);
        if(x != y) f[x] = y;
    }
    
    void makeSet() {
        for(int i = 1; i <= n; ++ i) f[i] = i;
    }
    
    void tarjan(const int u, const int ba) {
        dfn[u] = low[u] = ++ tot;
        for(int i = head[u]; i; i = nxt[i]) {
            int v = dot[i];
            if(v == ba) continue;
            if(dfn[v]) low[u] = min(low[u], dfn[v]);
            else {
                tarjan(v, u);
                low[u] = min(low[u], low[v]);
                if(low[v] > dfn[u]) unionSet(u, v);
            }
        }
    }
    
    int main() {
        int a, b;
        n = read(), m = read(), Q = read();
        makeSet();
        for(int i = 1; i <= m; ++ i) {
            a = read(), b = read();
            addEdge(a, b), addEdge(b, a);
        }
        tarjan(1, 0);
        while(Q --) {
            a = read(), b = read();
            if(findSet(a) == findSet(b)) puts("Y");
            else puts("N");
        }
        return 0;
    }
    
  • 相关阅读:
    uniapp版本迭代
    上传图像裁剪功能
    uniapp 复制到剪切板
    uniapp吸顶功能
    地图导航到目的地
    uniapp视频图片上传
    获取昨天今天明天的时间
    【VUE】 前端面试题小结
    vue获取当前时间 实时刷新
    CSS linear-gradient() 函数
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/12402819.html
Copyright © 2011-2022 走看看