E. Reachability from the Capital 解析(思維、SCC)

Codeforce 999 E. Reachability from the Capital 解析(思維、SCC)

今天我們來看看CF999E
題目連結linux

題目
給一個有向圖,和一個點\(s\)。求至少要蓋幾條路纔能夠從\(s\)到全部點。ios

前言

這題以前在Youtube上看到過了,結果還是寫了很久,主要是第一次寫SCC。
api

@copyright petjelinux 版權全部
觀看更多正版原始文章請至petjelinux的blog

想法

我們能夠找出全部強連通份量,然後紀錄每個份量的入度。入度為零的份量就必須從\(s\)連一條邊過去。(若是\(s\)所在份量的入度為零,解答要減\(1\))spa

程式碼:

const int _n=5010;
int t,n,m,s,u,v,in[_n],scc[_n],T;
stack<int> st;
VI G1[_n],G2[_n]/*,G3[_n]*/;
bool vis[_n];
void dfs1(int v){
  vis[v]=1;
  for(int u:G2[v])if(!vis[u])dfs1(u);
  st.push(v);
}
void dfs2(int v){
  vis[v]=1,scc[v]=T;
  for(int u:G1[v])if(!vis[u])dfs2(u);
}
main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  cin>>n>>m>>s;rep(i,0,m){cin>>u>>v;G1[u].pb(v),G2[v].pb(u);}
  rep(i,1,n+1)if(!vis[i])dfs1(i); memset(vis,0,sizeof vis);
  while(!st.empty()){
    if(!vis[st.top()])T++,dfs2(st.top());
    st.pop();
  }//下面一行是建縮點後的圖,這題(999E)不用真的把圖建起來,因此註解掉G3[i].pb(u)
  rep(i,1,n+1)for(int u:G1[i])if(scc[i]!=scc[u])/*G3[i].pb(u),*/in[scc[u]]++;
  int ans=0;rep(i,0,T)if(!in[i])ans++;
  cout<<ans-(in[scc[s]]==0)<<'\n';
  return 0;
}

標頭、模板請點Submission看
Submissioncode

相關文章
相關標籤/搜索