Reachability from the Capital CodeForces - 999E(强连通分量 缩点 入度为0的点)
标签:printf ffffff %s sig min == lin using vector
题意:
问至少加几条边 能使点s可以到达所有的点
解析:
无向图的连通分量意义就是 在这个连通分量里 没两个点之间至少有一条可以相互到达的路径
所以 我们符合这种关系的点放在一起, 由s向这些点的任意一个连边即可
即为求除s所在的连通分量以外的 入度为0的连通分量
#include #define mem(a, b) memset(a, b, sizeof(a))
#define rap(i, a, n) for(int i=a; i#define rep(i, a, n) for(int i=a; i#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define pd(a) printf("%d\n", a);
#define plld(a) printf("%lld\n", a);
#define pc(a) printf("%c\n", a);
#define ps(a) printf("%s\n", a);
#define MOD 2018
#define LL long long
#define ULL unsigned long long
using namespace std;
const int maxn = 10010, INF = 0x7fffffff;
vectorint> G[maxn];
int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt;
int in[maxn];
stackint> S;
int n, m, s;
void dfs(int u)
{
pre[u] = lowlink[u] = ++dfs_clock;
S.push(u);
for(int i=0; i)
{
int v = G[u][i];
if(!pre[v])
{
dfs(v);
lowlink[u] = min(lowlink[u], lowlink[v]);
}
else if(!sccno[v])
lowlink[u] = min(lowlink[u], pre[v]);
}
if(lowlink[u] == pre[u])
{
scc_cnt++;
for(;;)
{
int x = S.top(); S.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
void init()
{
dfs_clock = scc_cnt = 0;
mem(sccno, 0);
mem(pre, 0);
}
int main()
{
init();
int u, v;
cin>> n >> m >> s;
for(int i=0; i)
{
cin>> u >> v;
G[u].push_back(v);
}
for(int i = 1; i)
if(!pre[i]) dfs(i);
// cout
for(int i=1; i)
for(int j=0; j)
if(sccno[i] != sccno[G[i][j]])
in[sccno[G[i][j]]]++;
int cnt = 0;
if(in[sccno[s]] == 0)
cnt--;
for(int i=1; i)
{
if(in[i] == 0)
cnt++;
}
coutendl;
return 0;
}
Reachability from the Capital CodeForces - 999E(强连通分量 缩点 入度为0的点)
标签:printf ffffff %s sig min == lin using vector
原文地址:https://www.cnblogs.com/WTSRUVF/p/9655050.html
评论