(2019沈阳网络赛) B. Dudu's maze (概率)

传送门

解:比赛的时候思路跑偏了,看了题解才恍然大悟T T

cout的浮点数输出是真的麻烦呀 

#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=1e5+5;
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int T,n,m,k,fa[N],num[N],a[N];
vector<int> eg[N];
bool fg[N];
il void init(){
	for(int i=0;i<=n;++i) fa[i]=i,num[i]=1,fg[i]=0,eg[i].clear();
}
il int find(int x){
	if(x==fa[x]) return x;
	else return fa[x]=find(fa[x]);
}
il void unite(int x,int y){
	x=find(x),y=find(y);
	if(x==y) return;
	fa[x]=y,num[y]+=num[x];
}
int main(){
	std::ios::sync_with_stdio(0);cin.tie(0);
	cin>>T;
	while(T--){
		cin>>n>>m>>k;
		init();
		int x,y,cnt=0;
		for(int i=1;i<=m;++i){
			cin>>x>>y;
			eg[x].pb(y),eg[y].pb(x);
		}
		for(int i=1;i<=k;++i){
			cin>>x,fg[x]=1;
			a[++cnt]=x;
		}
		for(int i=1;i<=n;++i){
			if(fg[i]) continue;
			for(auto to:eg[i]){
				if(!fg[to]) unite(i,to);
			}
		}
		int rt=find(1),res=num[rt];
		if(res==n-k){
			cout<<fixed<<setprecision(8)<<1.0*res<<endl;
			continue;
		}
		double res2=0.0;
		for(int i=1;i<=cnt;++i){
			int tp=a[i],yes=0;
			for(auto to:eg[tp]){
				if(find(to)==rt){
					yes=1;
					break;	
				}
			}
			if(yes==1){
				int sum=0;
				for(auto to:eg[tp]){
					if(fg[to]) continue;
					if(find(to)==rt) continue;
					sum+=num[find(to)];
				}
				res2=max(res2,1.0*sum/SZ(eg[tp]));	
			} 
		}
		cout<<fixed<<setprecision(8)<<res2+1.0*res<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值