1. 程式人生 > >【Noip模擬 20161005】友好城市

【Noip模擬 20161005】友好城市

大小 整數 如果 top min 告訴 clu max tdi

問題描述

ww生活在美麗的ZZ國。ZZ國是一個有nn個城市的大國,城市之間有mm條單向公路(連 接城市ii、jj的公路只能從ii連到jj)。城市ii、jj是友好城市當且僅當從城市ii能到達城市jj並 且從城市jj能到達城市ii。如果kk個城市兩兩互為友好城市,那麽我們稱這kk個城市是友好 城市群,kk為友好城市群的大小。現在小ww想知道友好城市群的大小最大為多少,你能告訴 他嗎?

輸入格式

第一行包含兩個整數nn 和mm。

接下來mm 行,每行兩個整數ii和jj,表示有從城市ii到城市jj的一條單向公路。

輸出格式

共一行一個整數表示答案。

輸入樣例

10 12
3 7
1 2
4 5
7 10
10 8
6 8
2 1
3 8
10 3
6 8
7 3
4 1

輸出樣例

3

數據範圍

對於30%的數據,n,m100n,m≤100

對於80%的數據,n1000, m100000n≤1000, m≤100000

對於100%的數據,n,m100000

題目分析

我定睛一看就把Tarjan這糟老頭子拽出來了:你特麽又變著法子考我?然後我就寫完了代碼,下面獻上。

代碼實現

#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define int long long
#define RE register int
#define N 100001
int
m,n,cnt,tim,ans; int head[N],dfn[N],low[N]; stack<int>s; bitset<N>vis; struct aa{int v,next;}e[N<<1]; IL void addedge(RE u,RE v){ e[++cnt]=(aa){v,head[u]},head[u]=cnt; }IL void Tarjan(RE u){ dfn[u]=low[u]=++tim,vis[u]=1,s.push(u); for (RE v,i=head[u];i;i=e[i].next){
if (!dfn[v=e[i].v]) Tarjan(v),low[u]=min(low[u],low[v]); else if (vis[v]) low[u]=min(low[u],dfn[v]); }if (dfn[u]==low[u]){ RE sum=0; do{++sum,vis[s.top()]=0,s.pop();}while(s.top()^u); ans=max(ans,sum); } } signed main(){ // freopen("friend.in","r",stdin),freopen("friend.out","w",stdout); cin>>n>>m; for (RE i=1,u,v;i<=m;++i) cin>>u>>v,addedge(u,v); for (RE i=1;i<=n;++i) if (!dfn[i]) Tarjan(i); cout<<ans; }

代碼分析

第一次交沒有AC,因為我們的評測機爆炸了。註意退棧的操作,這一題不需要縮點,大家學了網絡流對Tarjan會懂得更多的。

我還要寫什麽呢,睡覺去了,整個晚上都沒有和她聯系,有點孤單。

【Noip模擬 20161005】友好城市