1. 程式人生 > >題解 CF1000E 【We Need More Bosses】

題解 CF1000E 【We Need More Bosses】

return index dfs 樹的直徑 ace min putc 目的 while

這道題絕不是紫題。。。


題目的意思其實是讓你求一個無向無重邊圖的直徑。

對於求直徑的問題我們以前研究過樹的直徑,可以兩遍dfs或者兩邊bfs解決。

對於圖顯然不能這樣解決,因為圖上兩點之間的簡單路徑不唯一。

那怎麽解決這個問題呢?

能不能把環都搞掉呢?

於是乎,我們想到了強連通分量。

因此先用tarjan縮一下點,重新建圖跑一個直徑就可以解決這個問題了。



AC代碼如下:

3053ms 23816kb

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 namespace
StandardIO { 6 7 template<typename T>inline void read (T &x) { 8 x=0;T f=1;char c=getchar(); 9 for (; c<0||c>9; c=getchar()) if (c==-) f=-1; 10 for (; c>=0&&c<=9; c=getchar()) x=x*10+c-0; 11 x*=f; 12 } 13
14 template<typename T>inline void write (T x) { 15 if (x<0) putchar(-),x*=-1; 16 if (x>=10) write(x/10); 17 putchar(x%10+0); 18 } 19 20 } 21 22 using namespace StandardIO; 23 24 namespace Solve { 25 26 const int N=300300;
27 28 int n,m,bcnt,index; 29 vector<int>graph[N],new_graph[N]; 30 int low[N],dfn[N],belong[N],instack[N],dis[N]; 31 stack<int>st; 32 33 inline void tarjan (int now,int father) { 34 low[now]=dfn[now]=++index; 35 st.push(now),instack[now]=1; 36 for (register int i=0; i<graph[now].size(); ++i) { 37 int to=graph[now][i]; 38 if (to==father) continue; 39 if (!dfn[to]) { 40 tarjan(to,now); 41 low[now]=min(low[now],low[to]); 42 } else if (instack[to]) { 43 low[now]=min(low[now],dfn[to]); 44 } 45 } 46 if (low[now]==dfn[now]) { 47 int v=-1;++bcnt; 48 while(v!=now){ 49 v=st.top(),st.pop(); 50 instack[v]=0,belong[v]=bcnt; 51 } 52 } 53 } 54 55 inline void dfs (int now,int fa) { 56 dis[now]=dis[fa]+1; 57 for (register int i=0; i<new_graph[now].size(); ++i) { 58 int to=new_graph[now][i]; 59 if (to!=fa) dfs(to,now); 60 } 61 } 62 63 inline int diameter () { 64 dfs(1,0); 65 int fur=1; 66 for (register int i=1; i<=bcnt; ++i) { 67 if (dis[i]>dis[fur]) fur=i; 68 } 69 dfs(fur,0); 70 int ans=0; 71 for (register int i=1; i<=bcnt; ++i) { 72 ans=max(ans,dis[i]); 73 } 74 return ans-1; 75 } 76 77 inline void solve () { 78 read(n),read(m); 79 for (register int i=1; i<=m; ++i) { 80 int x,y; 81 read(x),read(y); 82 graph[x].push_back(y); 83 graph[y].push_back(x); 84 } 85 for (register int i=1; i<=n; ++i) { 86 if (!dfn[i]) tarjan(i,0); 87 } 88 for (register int i=1; i<=n; ++i) { 89 for (register int j=0; j<graph[i].size(); ++j) { 90 int to=graph[i][j]; 91 if (belong[i]!=belong[to]) { 92 new_graph[belong[i]].push_back(belong[to]); 93 } 94 } 95 } 96 write(diameter()); 97 } 98 } 99 100 using namespace Solve; 101 102 int main () { 103 // freopen(".in","r",stdin); 104 // freopen(".out","w",stdout); 105 solve(); 106 }

題解 CF1000E 【We Need More Bosses】