ccf 201509-4 高速公路(強連通分量)
阿新 • • 發佈:2019-02-02
試題編號: | 201509-4 |
試題名稱: | 高速公路 |
時間限制: | 1.0s |
記憶體限制: | 256.0MB |
問題描述: |
問題描述
某國有n個城市,為了使得城市間的交通更便利,該國國王打算在城市之間修一些高速公路,由於經費限制,國王打算第一階段先在部分城市之間修一些單向的高速公路。 現在,大臣們幫國王擬了一個修高速公路的計劃。看了計劃後,國王發現,有些城市之間可以通過高速公路直接(不經過其他城市)或間接(經過一個或多個其他城市)到達,而有的卻不能。如果城市A可以通過高速公路到達城市B,而且城市B也可以通過高速公路到達城市A,則這兩個城市被稱為便利城市對。 國王想知道,在大臣們給他的計劃中,有多少個便利城市對。 輸入格式 輸入的第一行包含兩個整數n 接下來m行,每行兩個整數a, b,表示城市a有一條單向的高速公路連向城市b。 輸出格式 輸出一行,包含一個整數,表示便利城市對的數量。 樣例輸入 5 5 1 2 2 3 3 4 4 2 3 5 樣例輸出 3 樣例說明 城市間的連線如圖所示。有3個便利城市對,它們分別是(2, 3), (2, 4), (3, 4),請注意(2, 3)和(3, 2)看成同一個便利城市對。 評測用例規模與約定 前30%的評測用例滿足1 ≤ n ≤ 100, 1 ≤ m ≤ 1000; 前60%的評測用例滿足1 ≤ n ≤ 1000, 1 ≤ m ≤ 10000; 所有評測用例滿足1 ≤ n |
求出一共有幾個強連通分量,然後對於每一塊強連通分量,頂點數為n,則這塊裡的城市對數目為n*(n-1)/2,將所有的連通塊城市個數累加即可。
#include<bits/stdc++.h> #define inf 0x3f3f3f3f #define N 10000+10 using namespace std; stack<int>sta; vector<int>gra[N]; int dfn[N],low[N],now,vis[N],sum,num[N]; void tarjan(int s) { vis[s]=2; dfn[s]=low[s]=++now; sta.push(s); for(int i=0; i<gra[s].size(); i++) { int t=gra[s][i]; if(!dfn[t]) tarjan(t),low[s]=min(low[s],low[t]); else if(vis[t]==2) low[s]=min(low[s],dfn[t]); } if(low[s]==dfn[s]) { sum++; while(!sta.empty()) { int t=sta.top(); sta.pop(); vis[t]=1; num[sum]++; if(t==s)break; } } } int main() { int u,v,m,n; cin>>n>>m; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); now=sum=0; for(int i=1; i<=n; i++) gra[i].clear(); while(!sta.empty()) sta.pop(); for(int i=0; i<m; i++) { cin>>u>>v; gra[u].push_back(v); } for(int i=1; i<=n; i++) if(!dfn[i]) tarjan(i); int ans=0; for(int i=1; i<=sum; i++) ans += num[i]*(num[i]-1)/2; cout<<ans<<endl; return 0; }