题解 CF1000E 【We Need More Bosses】

这道题绝不是紫题。。。


题目的意思其实是让你求一个无向无重边图的直径。

对于求直径的问题我们以前研究过树的直径,可以两遍dfs或者两边bfs解决。

对于图显然不能这样解决,因为图上两点之间的简单路径不唯一。

那怎么解决这个问题呢?

能不能把环都搞掉呢?

于是乎,我们想到了强连通分量。

因此先用tarjan缩一下点,重新建图跑一个直径就可以解决这个问题了。



AC代码如下:

扫描二维码关注公众号,回复: 3700595 查看本文章

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 }

猜你喜欢

转载自www.cnblogs.com/ilverene/p/9841100.html
今日推荐