• 51nod 1076 2条不相交的路径 无向图强联通分量 trajan算法


    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     收藏
     关注
    给出一个无向图G的顶点V和边E。进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径。(两条路径不经过相同的边)
     
    (注,无向图中不存在重边,也就是说确定起点和终点,他们之间最多只有1条路)
    Input
    第1行:2个数M N,中间用空格分开,M是顶点的数量,N是边的数量。(2 <= M <= 25000, 1 <= N <= 50000)
    第2 - N + 1行,每行2个数,中间用空格分隔,分别是N条边的起点和终点的编号。例如2 4表示起点为2,终点为4,由于是无向图,所以从4到2也是可行的路径。
    第N + 2行,一个数Q,表示后面将进行Q次查询。(1 <= Q <= 50000)
    第N + 3 - N + 2 + Q行,每行2个数s, t,中间用空格分隔,表示查询的起点和终点。
    Output
    共Q行,如果从s到t存在2条不相交的路径则输出Yes,否则输出No。
    Input示例
    4 4
    1 2
    2 3
    1 3
    1 4
    5
    1 2
    2 3
    3 1
    2 4
    1 4
    Output示例
    Yes
    Yes
    Yes
    No
    No


    直接构图套强联通分量的模板 然后看询问的两个点是否联通
    一开始数组开小了 然后最后3个答案一直WA找了半天简直毒瘤啊...
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <iomanip>
    #include <math.h>
    #include <map>
    using namespace std;
    #define FIN     freopen("input.txt","r",stdin);
    #define FOUT    freopen("output.txt","w",stdout);
    #define INF     0x3f3f3f3f
    #define INFLL   0x3f3f3f3f3f3f3f
    #define lson    l,m,rt<<1
    #define rson    m+1,r,rt<<1|1
    typedef long long LL;
    typedef pair<int, int> PII;
    using namespace std;
    
    const int MX = 1e5 + 10;
    
    struct Edge {
        int u, v, nxt;
    } E[MX];
    int Head[MX], erear;
    void edge_init() {
        erear = 0;
        memset(Head, -1, sizeof(Head));
    }
    void edge_add(int u, int v) {
        E[erear].u = u;
        E[erear].v = v;
        E[erear].nxt = Head[u];
        Head[u] = erear++;
    }
    int n, m, IN[MX], cnt[MX], val[MX];
    int bsz, ssz, dsz;
    int Low[MX], DFN[MX];
    void Init_tarjan(int n) {
        bsz = ssz = dsz = 0;
        for(int i = 1; i <= n; ++i) Low[i] = DFN[i] = 0;
    }
    
    int Stack[MX], inStack[MX], Belong[MX];
    void trajan(int u, int e) {
        inStack[u] = 1;
        Stack[++ssz] = u;
        DFN[u] = Low[u] = ++dsz;
        for(int i = Head[u]; ~i; i = E[i].nxt) {
            int v = E[i].v;
            if((i ^ 1) == e) continue;
            if(!DFN[v]) {
                trajan(v, i);
                Low[u] = min(Low[u], Low[v]);
            } else if(inStack[v]) {
                Low[u] = min(Low[u], Low[v]);
            }
        }
        if(DFN[u] == Low[u]) {
            bsz++; int v;
            do {
                v = Stack[ssz--];
                inStack[v] = 0;
                Belong[v] = bsz;
            } while(ssz && v != u);
        }
    }
    void tarjan_solve(int n) {
        dsz = bsz = ssz = 0;
        memset(DFN, 0, sizeof(DFN));
        for(int i = 1; i <= n; i++) {
            if(!DFN[i]) trajan(i, -1);
        }
        /*缩点*/
        edge_init();
        for(int i = 0; i < 2 * m; i += 2) {
            int u = E[i].u, v = E[i].v;
            u = Belong[u]; v = Belong[v];
            if(u == v) continue;
            edge_add(u, v);
            edge_add(v, u);
        }
    }
    
    int main() {
        //FIN
        int m, n;
        while(~scanf("%d%d", &m, &n)) {
            edge_init();
            for(int i = 1; i <= n; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                edge_add(u, v);
                edge_add(v, u);
            }
            tarjan_solve(n);
            int Q;
            scanf("%d", &Q);
            for(int i = 1; i <= Q; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                if(Belong[u] == Belong[v]) printf("Yes
    ");
                else printf("No
    ");
            }
    
    
        }
        return 0;
    }
    

      



  • 相关阅读:
    Oracle数据库死锁和MySQL死锁构造和比较
    shell单引号中输出参数值
    视频流媒体服务器
    使用syncthing进行双机文件同步
    状态(State)模式--设计模式
    中介者(调停者)模式--设计模式
    链表的中间节点
    删除链表中的倒数第N个节点
    Logos讲解--逆向开发
    MonkeyDev安装--逆向开发
  • 原文地址:https://www.cnblogs.com/Hyouka/p/7407255.html
Copyright © 2020-2023  润新知