CCF 201509 4 高速公路

2021-07-10 04:13:20 字數 3492 閱讀 6903

問題描述

試題編號:

201509-4

試題名稱:

高速公路

時間限制:

1.0s

記憶體限制:

256.0mb

問題描述:

問題描述

某國有n個城市,為了使得城市間的交通更便利,該國國王打算在城市之間修一些高速公路,由於經費限制,國王打算第一階段先在部分城市之間修一些單向的高速公路。

現在,大臣們幫國王擬了乙個修高速公路的計畫。看了計畫後,國王發現,有些城市之間可以通過高速公路直接(不經過其他城市)或間接(經過乙個或多個其他城市)到達,而有的卻不能。如果城市a可以通過高速公路到達城市b,而且城市b也可以通過高速公路到達城市a,則這兩個城市被稱為便利城市對。

國王想知道,在大臣們給他的計畫中,有多少個便利城市對。

輸入格式

輸入的第一行包含兩個整數n, m,分別表示城市和單向高速公路的數量。

接下來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 ≤ 10000, 1 ≤ m ≤ 100000。

但是這裡我的**上傳之後只得到了40分,具體原因我也不是很清楚,對照了一下自己的**與標準答案,並沒有發現什麼錯誤。希望能有好心人幫我指出一下錯誤在哪,謝謝!

#include#include#include#includeusing namespace std;

const int white = 1; //未訪問

const int gray = 0; //正在棧中

const int black = -1; //已訪問完畢

int time = 1; //時間戳

long long int ans = 0; //解答

vectorvect[10010];

int cnt = 0;

stacksta; //訪問順序棧

class edgenode;

class vertexnodenode[10010];

void tarjan(int i)

else if (node[u].color == gray)

node[i].low = min(node[i].low, node[u].dfn);

temp = temp->next;

} node[i].color = black;

if (node[i].low == node[i].dfn)

while (i != j); }}

int main()

for (int i = 1; i <= m; i++)

for (int i = 1; i <= n; i++)

if (node[i].color == white)

tarjan(i);

for (int i = 1; i <= cnt; i++)

cout << ans << endl;

// system("pause");

return 0;

}

其實這篇大概在初八的樣子就應該放上來的,只不過因為自己偷懶,再加上最近又在忙物聯網創新大賽的事,因此就一直拖到了現在。。。ccf400分果然還是有難度啊,不知道乙個月的時間能不能抓緊補上來。感覺自己三月份應該會很忙的樣子,還要準備考研的事,真是痛苦。。。

2016/2/27新增:

重新寫了一遍**,然後發現我之前參考的那篇文章思路是錯的。。。我也是有點醉。參考後面那篇文章寫的**之後分數提高到了60分,演算法思路應該沒有什麼問題了,提示的錯誤是**超時。對照了一下標準答案,發現標準答案裡根本就沒用class,而是用了大量的陣列與vector來模擬了整個圖的資料結構。我覺得應該是自己設計的資料結構訪問太慢的原因,晚點會嘗試把我的**再改一下。

ps:嘗試著使用了一下dev c++,感覺真是難用。。。現在才真切感受到乙個好的ide對於程式設計是有多麼大的提公升。。。

#include#include#include#includeusing namespace std;

int time=0;

long int ans=0;

stacksta;

vectorvec;

int cnt=0;

class edgenode;

class vertexnodenode[10001];

void tarjan(int i)

else if(node[u].in_stack)

temp=temp->next;

} if(node[i].low==node[i].dfn)while(i!=j);

if(cnt!=1) vec.push_back(cnt); }}

int main()

for(int i=0;i>a>>b;

edgenode *e=new edgenode();

e->adjvex=b;

e->next=node[a].firstedge;

node[a].firstedge=e;

} for(int i=1;i<=n;i++)

if(!node[i].visited)

tarjan(i);

for(int i=0;i2016/2/29新增:

第三次嘗試編寫tarjan演算法,這次將圖的所有資料全部用陣列和vector來儲存,果然用時降到了200+ms,但問題是這個程式只有80分!80分!我都快要瘋了。。。死活查不出錯誤在哪。。。只能等我之後有心情再來重新寫了。。。

#include#include#include#include#includeusing namespace std;

int dfn[10001];

int low[10001];

bool in_stack[10001];

bool visited[10001];

vectorgraph[10001];

stacksta;

int time=0;

int ans=0;

void tarjan(int i)

for(int i=1;i<=n;i++)

if(!visited[i])

tarjan(i);

cout<

CCF 201509 4 高速公路

問題描述 某國有n個城市,為了使得城市間的交通更便利,該國國王打算在城市之間修一些高速公路,由於經費限制,國王打算第一階段先在部分城市之間修一些單向的高速公路。現在,大臣們幫國王擬了乙個修高速公路的計畫。看了計畫後,國王發現,有些城市之間可以通過高速公路直接 不經過其他城市 或間接 經過乙個或多個其...

CCF 201509 4 高速公路(強連通分量)

求有多少個結點對能夠互相到達 思路一 50分 對每個結點dfs,求傳遞閉包,時間為o v e 簡單,但是超時 思路二 100分 計算圖的強連通分量 scc 各個分量裡面的點都是可以相互到達的 scc演算法 o v e 強連通分量 strongly connected components dfs求拓...

CCF201509 4 高速公路 強連通分量

傳送門 ccf201509 4 高速公路 tarjan強連通分量演算法的模板題。求得強連通分量後,包含的點為cnt個,其中的任意兩個城市都是便利城市對,數量為 include define ll long long define inf 0x3f3f3f3f using namespace std ...