CodeForces - 999E
題目
思路
一開始陷入了誤區,我以爲強連通分量縮點之後,每一個點重新連一條邊成一個鏈就是答案,我的答案就是scc-1結果wa了,後來一想因爲兩個強聯通分量直接可能已經有邊了,就不用再加了,看了一篇題解看到說統計入度爲0,後來想想也對,只要讓s連接入度爲0的點,剩下的點都可以經過,那麼縮點,新建一張圖,統計入度爲0的點,即統計入讀爲0的強聯通分量即可。
代碼
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
using namespace std;
#define dbg(x) cerr << #x " = " << x <<endl;
typedef pair<int, int> P;
typedef long long ll;
const int MAXN = 5005;
const int MAXM = 5005;
struct Edge
{
int to, next;
}edge[MAXM];
int Low[MAXN], DFN[MAXN], num[MAXN], Belong[MAXN], Stack[MAXN];
bool Instack[MAXN];
int scc, Index, top;
int head[MAXN], tot;
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void init()
{
tot = 0;
memset(head, -1, sizeof(head));
}
void tarjan(int u)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].to;
if(!DFN[v])
{
tarjan(v);
Low[u] = min(Low[u], Low[v]);
}
else if(Instack[v])
{
Low[u] = min(Low[u], DFN[v]);
}
}
if(Low[u] == DFN[u])
{
scc++;
do{
v = Stack[--top];
Instack[v] = 0;
Belong[v] = scc;
num[scc]++;
}while(u != v);
}
}
void solve(int N)
{
memset(DFN, 0, sizeof(DFN));
memset(Instack, 0, sizeof(Instack));
memset(num, 0, sizeof(num));
Index = scc = top = 0;
for(int i = 1; i <= N; i++)
{
if(!DFN[i])
{
tarjan(i);
}
}
}
P a[MAXN];
int In[MAXN] ={0};
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
init();
int n, m, s;
cin >> n >> m >> s;
for(int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
addedge(u, v);
a[i].first = u;
a[i].second = v;
}
solve(n);
/*for(int i = 1; i <= n; i++)
{
cout << Belong[i] << ' ';
}
cout << endl;*/
for(int i = 0; i < m; i++)
{
int u = a[i].first;
int v = a[i].second;
if(Belong[u] != Belong[v])
{
In[Belong[v]]++;
}
}
int ans = 0;
for(int i = 1; i <= scc; i++)
{
if(i != Belong[s] && In[i] == 0) ans++;
}
cout << ans << endl;
}