欢迎来到Introzo百科
Introzo百科
当前位置:网站首页 > 科学 > 【2020小米网选D Router Mesh】Tarjan问每个点属于哪一个点双连通组件

【2020小米网选D Router Mesh】Tarjan问每个点属于哪一个点双连通组件

日期:2023-10-01 13:22

传送门 给定一个无向图,对每个节点进行查询。问题是,如果删除这个点(及其所有相关边),整个图中会有多少个连通块? 用Tarjan算法的思想来写,dfn[i]表示节点i的dfs阶,而low[i]表示从节点i dfs可以到达的dfn值最小的节点的dfn值。如果u是当前节点,v是u的未访问子节点,如果对v完成dfs后,得到low[v] <= dfn[u],那么就意味着从u的父节点,经过u,我们可以在到达v时,如果删除节点u,则无法到达节点v。这相当于删除节点u。 u 和节点 v 的父节点会被分成两个连通的块,即两部分不能互相到达。因此,你只需要计算你有多少个节点。子节点v满足Fuzzy [v] <= dfn [u]。当然,u的父节点也是子节点,所以需要+1来包含父节点。但每次dfs的起点都没有父节点,所以不需要+1。 总结一下,删除节点u有什么影响呢?假设删除节点 u 将添加 ans[u] 连接块。该无向图最初包含 m 个连通块。该节点原本属于 1 个连通块。删除后,会添加 ans[u] 个连通块。 block,那么删除该节点后的连通块数应为m-1+ans[u]。 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #define IOS ios::sync_with_stdio(false) #define show(x) std::cerr << #x << " = " << x << std::endl; #define mem(a,x) memset(a,x,sizeof(a)) #define Rint 寄存器 int 使用命名空间 std; typedef 长长 ll; 常量 int maxn=1e6+10; 常量 int maxm=2e6+10; const ll mod=1e9+7;const 双 PI=acos(-1.0); 常量双 eps=1e-7; ll qpow(ll a,ll n){a%=mod;ll ans=1;while(n){if(n%2)ans=ans*a%mod;n/=2;a=a*a% mod;}返回 ans;} int dcmp(double x){if(fabs(x)0)返回 1;返回 -1;} 命名空间 Fast_IO{const int MAXL((1 << 18) + 1);int iof, iotp;char ioif[MAXL], *ioiS, *ioiT, ioof[MAXL],*iooS=ioof,*iooT=ioof+MAXL-1,ioc,iost[55];char Getchar(){if (ioiS == ioiT){ioiS=ioif;ioiT=ioiS+fread(ioif,1,MAXL,stdin);return (ioiS == ioiT ? EOF : *ioiS++);}else return (*ioiS++);}void Write(){fwrite(ioof,1,iooS-ioof,stdout);iooS=ioof;}void Putchar(char x){*iooS++ = x;if (iooS == iooT)Write();}inline int read(){int x=0;for(iof=1,ioc=Getchar();(ioc<'0'||ioc>'9')&&ioc!=EOF;)iof=ioc=='-'?-1:1,ioc=Getchar();if(ioc==EOF)退出(0);for(x=0;ioc<='9'&&ioc>='0';ioc=Getchar())x=(x<<3)+(x<<1)+(ioc^48);return x*iof;}inline long long read_ll(){long long x=0;for(iof=1,ioc=Getchar();(ioc<'0'||ioc>'9')&&ioc!=EOF;)iof=ioc=='-' ?-1:1,ioc=Getchar();if(ioc==EOF)exit(0);for(x=0;ioc<='9'&&ioc>='0';ioc=Getchar())x=(x<<3)+(x<<1)+(ioc^48);return x*iof;}template void Print(Int x, char ch = '\0'){if(!x)Putchar('0');if(x<0)Putchar('-'),x=-x;while(x )iost[++iotp]=x%10+'0',x/=10;while(iotp)Putchar(iost[iotp--]);if (ch)Putchar(ch);}void Getstr(char * s, int &l){for(ioc=Getchar();ioc==' '||ioc=='\n'||ioc=='\t';)ioc=Getchar();if(ioc== EOF)exit(0);for(l=0;!(ioc==' '||ioc=='\n'||ioc=='\t'||ioc==EOF);ioc=Getchar( ))s[l++]=ioc;s[l] = 0;}void Putstr(const char *s){for(int i=0,n=strlen(s);i

关灯