Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)
2015-08-18 10:36
441 查看
题目地址:http://codeforces.com/contest/506/problem/B
先用强连通判环,然后转化成无向图,找无向图连通块,若一个有n个点的块内有强连通环,那么需要n条边,即正好首尾相连形成一条环,那么有了这个环之后,在这个块内的所有要求都能实现。如果没有强连通环,那么就是一棵树,那么只需要n-1条边即可。
代码如下:
先用强连通判环,然后转化成无向图,找无向图连通块,若一个有n个点的块内有强连通环,那么需要n条边,即正好首尾相连形成一条环,那么有了这个环之后,在这个块内的所有要求都能实现。如果没有强连通环,那么就是一棵树,那么只需要n-1条边即可。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> #include <time.h> using namespace std; #define LL long long #define pi acos(-1.0) #pragma comment(linker, "/STACK:1024000000") const int mod=1e9+7; const int INF=0x3f3f3f3f; const double eqs=1e-9; const int MAXN=100000+10; int head[MAXN], cnt; int dfn[MAXN], low[MAXN], scc, belong[MAXN], instk[MAXN], stk[MAXN], indx, tot[MAXN], top; int vis[MAXN]; int flag, num; struct node { int u, v, next; }edge[MAXN<<1]; void add(int u, int v) { edge[cnt].u=u; edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } void init() { memset(head,-1,sizeof(head)); cnt=indx=top=0; memset(dfn,0,sizeof(dfn)); memset(instk,0,sizeof(instk)); memset(tot,0,sizeof(tot)); } void tarjan(int u) { dfn[u]=low[u]=++indx; stk[++top]=u; instk[u]=1; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(instk[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ scc++; while(1){ int v=stk[top--]; belong[v]=scc; instk[v]=0; tot[scc]++; if(u==v) break; } } } void dfs(int u) { num++; vis[u]=1; if(tot[belong[u]]>=2) flag=1; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(vis[v]) continue ; dfs(v); } } int main() { int n, m, u, v, i, j, ans; while(scanf("%d%d",&n,&m)!=EOF){ init(); while(m--){ scanf("%d%d",&u,&v); add(u,v); } ans=0; for(i=1;i<=n;i++){ if(!dfn[i]) tarjan(i); } m=cnt; for(i=0;i<m;i++){ u=edge[i].u; v=edge[i].v; add(v,u); } memset(vis,0,sizeof(vis)); ans=0; for(i=1;i<=n;i++){ if(!vis[i]){ num=flag=0; dfs(i); ans+=num-1+flag; } } printf("%d\n",ans); } return 0; }