小雀和他的王国

题目描述
年纪轻轻的小雀当上了国王。
小雀的王国中一共有n座城市(编号为1~n),被m条双向的高速公路连接,任意两个城市之间都可以通过若干条高速公路互相到达。
但是在小雀的王国里,经常发生自然灾害。一次突发的自然灾害会随机破坏一条高速公路,并且有可能使得某两个城市之间无法到达彼此,这样整个王国就不能继续正常运转了。小雀为此很是苦恼。
于是小雀决定再修建一条高速公路,连接某两个城市,使得下一次突发自然灾害的时候,整个王国不能继续正常运转的概率最小。但是他不知道该如何选择新高速公路所连接的两个城市。
请你帮助他选择新建高速的方案,并求出新的高速公路建成之后,突发自然灾害时,整个王国不能继续正常运转的最小概率。答案对109+7取模。
对于100%的数据,2≤ n,m ≤ 200000;
输入描述:
第一行包含两个整数n,m,表示城市的数量和现有的高速公路的数量。
接下来m行,每行包含两个整数ui,vi,表示一条高速公路所连接的两个城市的编号。
输出描述:
一行一个整数,表示最小概率。
示例1
输入
复制
7 7
1 2
1 3
1 6
2 4
2 5
4 5
6 7
输出
复制
125000001


比赛的时候手速慢了几分钟,没拿到first blood。

很明显,对于双连通分量里面,无论怎么断边,都不可能分开。所以很明显的先双连通分量缩点。

那么对于现在的一棵树,我们连一条边,会形成环,我们肯定想环最大。所以就是直径啦,然后两次bfs求一下直径即可。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
const int N=2e5+10,M=4e5+10;
int n,m,dfn[N],low[N],brige[M],cnt,col[N],co,p1,p2,mx,d[N],vis[N];
int head[N],nex[M],to[M],tot=1;
stack<int> st;	vector<int> g[N];
inline void add(int	a,int b){to[++tot]=b; nex[tot]=head[a]; head[a]=tot;}
void Tarjan(int x){
	dfn[x]=low[x]=++cnt; st.push(x); vis[x]=1;
	for(int i=head[x];i;i=nex[i]){
		if(brige[i])	continue;
		brige[i]=brige[i^1]=1;
		if(!dfn[to[i]]){
			Tarjan(to[i]);	low[x]=min(low[x],low[to[i]]);
		}else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
	}
	if(dfn[x]==low[x]){
		int u;	co++;
		do{
			u=st.top();	st.pop(); col[u]=co;
		}while(u!=x);
	}
}
int bfs(int s){
	queue<int> q;	q.push(s);	memset(d,-1,sizeof d); d[s]=mx=0; int p=s;
	while(q.size()){
		int u=q.front();	q.pop();
		for(int i=0;i<g[u].size();i++){
			int to=g[u][i];
			if(d[to]==-1){
				d[to]=d[u]+1;	q.push(to);
				if(d[to]>mx)	mx=d[to],p=to;
			}
		}
	}
	return p;
}
int qmi(int a,int b=mod-2){
	int res=1;
	while(b){
		if(b&1)	res=res*a%mod; a=a*a%mod; b>>=1;
	}
	return res;
}
signed main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1,a,b;i<=m;i++)	cin>>a>>b,add(a,b),add(b,a);
	for(int i=1;i<=n;i++)	if(!dfn[i])	Tarjan(i);
	for(int i=1;i<=n;i++){
		for(int j=head[i];j;j=nex[j]){
			if(col[i]==col[to[j]])	continue;
			g[col[i]].push_back(col[to[j]]);
		}
	}
	p1=bfs(1);	p2=bfs(p1);
	cout<<((co-1-mx)*qmi(m+1))%mod<<endl;
	return 0;
}
发布了416 篇原创文章 · 获赞 228 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/103739806
今日推荐