萌新第一次学期望DP
  • 板块灌水区
  • 楼主f_hxr_
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/8/12 16:32
  • 上次更新2023/11/3 04:15:46
查看原帖
萌新第一次学期望DP
754467
f_hxr_楼主2023/8/12 16:32

rt,还有个玄学的原因就是,22行取最大值的代码,用<就样例1AC样例3wa,用<=就样例1wa样例3AC

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn=500005;
LL N,M;
LL head[maxn],nxt[maxn],to[maxn],cnt;
LL head2[maxn],nxt2[maxn],to2[maxn],cnt2;
LL deg[maxn];
double f[maxn],G[maxn],ans=1e9+7;
void edge(LL U,LL V){
	nxt[++cnt]=head[U];//反边拓扑 
	to[cnt]=V;head[U]=cnt;
	nxt2[++cnt2]=head2[V];//正边找最大期望点 
	to2[cnt2]=U;head2[V]=cnt2;
	return;
}
LL f_hxr_(LL v){//find height x and return
	if(v==0)return 0;
	LL ret=0;
	for(int i=head2[v];i;i=nxt2[i]){
			if(ret==0)ret=i;
			else ret=(G[to[ret]]<=G[to[i]]?i:ret);//好玄学啊 (指<=#1WA#3AC,<#1AC#3WA)
		}
	return ret;
}
void Topsort(int v){
	memset(f,0,sizeof(f));
	queue<int>q;
	int T[maxn];
	LL e=f_hxr_(v);
	deg[to[e]]--;
	for(int i=0;i<=N;i++)T[i]=deg[i];
	q.push(N);
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=head[x];i;i=nxt[i]){
			if(i==e)continue;
			int p=to[i];
			f[p]+=(f[x]+1.0)/deg[p];
			T[p]--;
			if(T[p]==0)q.push(p);
		}
	}
	deg[to[e]]++;
	return;
}
int main(){
	cin>>N>>M;
	for(int i=1;i<=M;i++){int a,b;cin>>a>>b;edge(b,a);deg[a]++;} 
	Topsort(0);
	//特判:再多删一条边就要爆炸 
	int T=0;
	for(int i=1;i<=N;i++)
		if(deg[i]==1)T++;
	if(T==N){cout<<f[1];return 0;}
	for(int i=1;i<=N;i++)G[i]=f[i];
	//一点一边一期望,每个点都试一遍 
	for(int i=1;i<=N;i++){
		if(deg[i]==1)continue;//特判:再多删一条边就要融化 
		Topsort(i);
		ans=min(ans,f[1]);
	}
	printf("%.11lf",ans);
	return 0;
}
2023/8/12 16:32
加载中...