tarjan求强连通分量
http://poj.org/problem?id=3180
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<iomanip> #include<cmath> #include<algorithm> #include<vector> #include<cstring> #include<queue> #include<map> #include<string> #include<stack> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) #define lowbit(x) ((x)&(-x)) const double pi=4.0*atan(1.0); const int maxn=1e5+8; typedef long long LL; typedef unsigned long long ULL; const LL mod=1e9+7; const ULL base=1e7+7; using namespace std; struct node{ int to,nxt; }g[maxn*2]; int head[maxn]; int cnt=0; void add(int u,int v){ g[cnt].to=v; g[cnt].nxt=head[u]; head[u]=cnt++; } int deep=0; int dfn[maxn],low[maxn]; bool vis[maxn]; int Stack[maxn]; int tail=0; int ans=0; void tarjan(int u){ dfn[u]=++deep; low[u]=deep; Stack[++tail]=u; vis[u]=1; int t=head[u]; int r=0; while(t!=-1){ if(!dfn[g[t].to]){ tarjan(g[t].to); low[u]=min(low[u],low[g[t].to]); } else{ if(vis[g[t].to]){ low[u]=min(low[u],low[g[t].to]); } } t=g[t].nxt; } if(dfn[u]==low[u]){ while(Stack[tail]!=u){ vis[Stack[tail]]=0; tail--; r=1; } vis[Stack[tail]]=0; tail--; } ans+=r; } int main(){ memset(head,-1,sizeof(head)); int n,m,x,y; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); add(x,y); } for(int i=1;i<=n;i++){ if(!dfn[i]){ tarjan(i); } } cout<<ans<<endl; }
无向图缩点
http://codeforces.com/group/w1oiqifZbS/contest/652/problem/E
#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) #define lowbit(x) ((x)&(-x)) const double pi=4.0*atan(1.0); const int maxn=3e5+8; typedef long long LL; typedef unsigned long long ULL; const LL mod=1e9+7; const ULL base=1e7+7; using namespace std; struct node{ int to,nxt; bool val; }g[maxn*2],gg[maxn*2]; int head[maxn],head2[maxn]; int cnt=0; void add(int u,int v,bool val){ g[cnt].to=v; g[cnt].nxt=head[u]; g[cnt].val=val; head[u]=cnt++; } int deep=0; int dfn[maxn],low[maxn]; bool vis[maxn]; bool used[maxn]; int Stack[maxn]; bool a[maxn]; int color[maxn]; int tot=0; int tail=0; int n,m; void tarjan(int u,int fa){ dfn[u]=++deep; low[u]=deep; Stack[++tail]=u; vis[u]=1; int t=head[u]; while(t!=-1){ if(g[t].to==fa){ t=g[t].nxt; continue; } if(!dfn[g[t].to]){ tarjan(g[t].to,u); low[u]=min(low[u],low[g[t].to]); } else{ if(vis[g[t].to]){ low[u]=min(low[u],low[g[t].to]); } } t=g[t].nxt; } if(dfn[u]==low[u]){ tot++; while(Stack[tail]!=u){ vis[Stack[tail]]=0; color[Stack[tail]]=tot; tail--; } vis[Stack[tail]]=0; color[Stack[tail]]=tot; tail--; } } void add2(int u,int v,int val){ gg[cnt].to=v; gg[cnt].nxt=head2[u]; gg[cnt].val=val; head2[u]=cnt++; } void suodian(){ for(int i=1;i<=n;i++){ int t=head[i]; while(t!=-1){ if(color[i]==color[g[t].to]){ a[color[i]]+=g[t].val; } else if(g[t].to>i){ //cout<<i<<' '<<g[t].to<<endl; add2(color[i],color[g[t].to],g[t].val); add2(color[g[t].to],color[i],g[t].val); } t=g[t].nxt; } } } bool ans=0; void dfs2(int u,int fa,int aim,bool re){ //cout<<u<<endl; if(u==aim){ ans+=re; return ; } int t=head2[u]; while(t!=-1){ if(gg[t].to!=fa){ dfs2(gg[t].to,u,aim,re+gg[t].val+a[gg[t].to]); } t=gg[t].nxt; } } int main(){ memset(head,-1,sizeof(head)); memset(head2,-1,sizeof(head2)); int x,y,val; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&val); add(x,y,(bool)val); add(y,x,(bool)val); } int s,t; scanf("%d%d",&s,&t); for(int i=1;i<=n;i++){ if(!dfn[i]){ tarjan(i,0); } } cnt=0; suodian(); dfs2(color[s],0,color[t],a[color[s]]); if(ans){ cout<<"YES"<<endl; } else{ cout<<"NO"<<endl; } }