51nod 1076 2条不相交的路径 无向图强联通分量 trajan算法
Posted Hyouka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n"); else printf("No\n"); } } return 0; }
以上是关于51nod 1076 2条不相交的路径 无向图强联通分量 trajan算法的主要内容,如果未能解决你的问题,请参考以下文章