标签:dfs highlight 链接 for using max div bit main
http://acm.hdu.edu.cn/showproblem.php?pid=6736
在给定图中寻找所有最小环
保证不存在一条边经过两个简单环
$1\leq n \leq 300 000$
$1\leq m \leq 500 000$
每次遍历到某个点时入栈,遍历结束时出栈
依次把点加入栈中,如果下一个点在栈中,那么这里肯定构成了一个简单环
只需要计算栈中到达下一点元素的数量就行,不需要出栈
比赛的时候没想到这个方法,队友给出正确思路,但是实现时没写好,背锅
#include<bits/stdc++.h> #define ll long long #define pic pair<int,char> using namespace std; const int maxn=3e5+7; const int mod= 998244353; vector<int>ve[maxn]; int ins[maxn],top,sk[maxn],n,m,vis[maxn]; ll ans=1; ll qpow(int a,int b){ ll res=1,k=a; while(b){ if(b&1)res=res*k%mod; k=k*k%mod; b/=2; } return res; } void dfs(int x,int f){ sk[++top]=x; ins[x]=1; vis[x]=1; for(int i=0;i<ve[x].size();i++){ int v=ve[x][i]; if(vis[v]==0){ dfs(v,x); }else if(v!=f&&ins[v]){ int res=1; int zz=top; while(1){ zz--; res++; // cout<<zz<<endl; if(sk[zz]==v)break; } if(res){ // cout<<res<<endl; m-=res; ans=(qpow(2,res)-1+mod)%mod*ans%mod; } } } ins[sk[top]]=0; --top; } int main(){ // cout<<qpow(2,10)<<endl; while(scanf("%d %d",&n,&m)==2){ for(int i=1;i<=n;i++)ve[i].clear(); top=0; memset(ins,0,sizeof(ins)); memset(vis,0,sizeof(vis)); for(int i=1;i<=m;i++){ int a,b; scanf("%d %d",&a,&b); ve[a].push_back(b); ve[b].push_back(a); } for(int i=1;i<=n;i++){ if(vis[i]==0){ dfs(i,0); } } ans=qpow(2,m)*ans%mod; printf("%lld\n",ans); ans=1; } return 0; } /* 7 9 1 2 1 3 2 3 3 4 4 5 5 3 3 6 3 7 6 7 */
标签:dfs highlight 链接 for using max div bit main
原文地址:https://www.cnblogs.com/carcar/p/11604445.html