牛客练习赛 56 E

题目链接

这道题其实并不难,为什么要写他呢? 因为被他坑了

题目:

给一个图,自己加上一条边后,问随机删去一条边后让图不连通的最小概率。
很明显缩点建图 然后 跑个树的直径
设直径为 d 缩点图上共 m 条边 原先图*** s 条边 答案就是 (m-d)/(s+1)
但是 只能过%95的样例 为什么??
有重边
好吧 我的板子有问题
那个Tra……的算法
无向图求缩点:我本来写的是防止回到他的上一个节点 x==fa continue;
但是这样的话如果这两个节点间有两条边 他就是一个强连通分量 就可以回到上一个节点所以板子改进一下。。。

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 2e5+5;
vector<int> vv[maxn];
int dfn[maxn];
int low[maxn];
int col[maxn];
int vis[maxn];
int pos;
stack<int> ss;
int cnt;
void dfs(int x,int fa)
{
   
// printf("%d\n",x);
	dfn[x] = low[x] = ++ pos;
	ss.push(x);
	vis[x] = 1;
	int f = 0;
	for (int i = 0; i < vv[x].size(); i ++ )
	{
   
		int v = vv[x][i];
		if(v == fa)
		{
   
			f++;
			if(f == 1)
				continue;
		}
			
		if(dfn[v] == 0)
		{
   
			dfs(v,x);
			low[x] = min(low[x],low[v]);
		}
		else
			low[x] = min(low[x],dfn[v]);
	}
	if(dfn[x] == low[x])
	{
   
		++cnt;
		while(ss.top()!=x)
		{
   
			col[ss.top()] = cnt;
			vis[ss.top()] = 0;
			ss.pop();
		}
		col[x] = cnt;
		vis[x] = 0;
		ss.pop();
	}
}
vector<int> sd[maxn];
int dep[maxn];
int root; 
void dfs2(int x,int fa,int dp)
{
   
	dep[x] = dp;
	if(dep[x] >= dep[root])
	{
   
		root = x;
	}
	for (int i = 0; i< sd[x].size(); i ++ )
	{
   
		int v = sd[x][i];
		if(v == fa)
			continue;
		dfs2(v,x,dp+1);
	}
}

ll quick(ll a,ll b)
{
   
	ll ans = 1;
	while(b)
	{
   
		if(b & 1)
		{
   
			ans = ans * a % mod;
		}
		a = a*a%mod;
		b >>= 1;
	}
	return ans%mod;
}

int main()
{
   
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 0; i < m; i ++ )
	{
   
		int x,y;
		scanf("%d%d",&x,&y);
		vv[x].push_back(y);
		vv[y].push_back(x);
	}
	for (int i = 1; i <= n; i ++ )
	{
   
		if(dfn[i] == 0)
		{
   
			dfs(i,-1);
		}
	}
// for (int i= 1; i <= n; i ++ )
// {
   
// printf("%d ",col[i]);
// }
	int s = 0;
	for (int i = 1; i <= n; i ++ )
	{
   
		int x = col[i];
		for (int j = 0 ;j < vv[i].size(); j ++ )
		{
   
			int y = col[vv[i][j]];
			if(x == y)
				continue;
			sd[x].push_back(y);
			s++;
		}
	}
// printf("%d\n",s);
	s/=2;
	root = 0;
	dep[0] = 0;
	dfs2(1,-1,1);
	int x = root;
	root = 0;
	dep[0] = 0;
	dfs2(x,-1,1);
	s -= dep[root] - 1;
// printf("%d\n",s);
	ll ans = 1ll * s * quick(1ll*m+1,mod-2) %mod;
	printf("%lld\n",ans);
}