zoukankan      html  css  js  c++  java
  • BZOJ 1415 聪聪和可可

    (N^2)
    DP[C][M]
    废状态多
    不好确定顺序
    记忆化搜索
    注意聪聪走编号小的点

    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    const int MAXN=1011;
    const int MAXM=1011;
    const int INF=1034567890;
    
    int N, M;
    int S, T;
    
    int Dis[MAXN][MAXN];
    double F[MAXN][MAXN];
    bool Vis[MAXN][MAXN];
    
    struct Vert{
    	int FE;
    	int Dis;
    	int Bfn;
    	int Deg;
    } V[MAXN];
    
    struct Edge{
    	int x, y, next;
    } E[MAXM<<1];
    
    int Ecnt=0;
    
    void addE(int a, int b){
    	++Ecnt;
    	E[Ecnt].x=a;E[Ecnt].y=b;E[Ecnt].next=V[a].FE;V[a].FE=Ecnt;
    }
    
    int Q[MAXN], Head, Tail;
    int BFN=0;
    
    void BFS_init(){
    	Head=1;Tail=1;
    	++BFN;
    }
    
    void BFS(int at){
    	BFS_init();
    	V[at].Dis=0;
    	Q[Tail++]=at;
    	V[at].Bfn=BFN;
    	while(Head<Tail){
    		at=Q[Head++];
    		for(int k=V[at].FE, to;k>0;k=E[k].next){
    			to=E[k].y;
    			if(V[to].Bfn==BFN)	continue;
    			V[to].Dis=V[at].Dis+1;
    			Q[Tail++]=to;
    			V[to].Bfn=BFN;
    		}
    	}
    }
    
    double DP(int s, int t){
    	if(s==t)	return 0.0;
    	if(Dis[s][t]<=2)	return 1.0;
    	if(Vis[s][t])	return F[s][t];
    	int s1=N+1, s1d=INF;
    	for(int k=V[s].FE, to;k>0;k=E[k].next){
    		to=E[k].y;
    		if(Dis[to][t]<s1d || (Dis[to][t]==s1d && to<s1)){
    			s1=to;
    			s1d=Dis[to][t];
    		}
    	}
    	if(s1d>=INF)	return 1e9;
    	int s2=N+1, s2d=INF;
    	for(int k=V[s1].FE, to;k>0;k=E[k].next){
    		to=E[k].y;
    		if(Dis[to][t]<s2d || (Dis[to][t]==s2d && to<s2)){
    			s2=to;
    			s2d=Dis[to][t];
    		}
    	}
    	if(s2d>=INF)	return 1e9;
    	double ret=1.0, p=1.0/(double)(V[t].Deg+1);
    	for(int k=V[t].FE, to;k>0;k=E[k].next){
    		to=E[k].y;
    		ret+=p*DP(s2, to);
    	}
    	ret+=p*DP(s2, t);
    	Vis[s][t]=true;F[s][t]=ret;
    	return ret;
    }
    
    int main(){
    	ios_base::sync_with_stdio(false);
    	
    	cin >> N >> M;
    	cin >> S >> T;
    	
    	for(int i=1, a, b;i<=M;++i){
    		cin >> a >> b;
    		addE(a, b);addE(b, a);
    		++V[a].Deg;++V[b].Deg;
    	}
    	
    	for(int i=1;i<=N;++i)
    		for(int j=1;j<=N;++j)
    			Dis[i][j]=INF;
    	
    	for(int i=1;i<=N;++i){
    		BFS(i);
    		for(int j=1;j<=N;++j)
    			Dis[i][j]=V[j].Dis;
    	}
    	
    	cout << fixed << setprecision(3) << DP(S, T) << endl;
    	
    	return 0;
    }
    
    /*
    4 3
    1 4
    1 2
    2 3
    3 4
    
    1.500
    
    */
    
    /*
    9 9
    9 3
    1 2
    2 3
    3 4
    4 5
    3 6
    4 6
    4 7
    7 8
    8 9
    
    2.167
    
    */
    
  • 相关阅读:
    【leetcode】1534. 统计好三元组
    【leetcode】1351. 统计有序矩阵中的负数
    【leetcode】1523. 在区间范围内统计奇数数目
    【leetcode】204. 计数质数
    【leetcode】993. 二叉树的堂兄弟节点
    【leetcode】1598. 文件夹操作日志搜集器
    【leetcode】1389. 按既定顺序创建目标数组
    【leetcode】增减字符串匹配
    【leetcode】1185.一周中的第几天
    052-158
  • 原文地址:https://www.cnblogs.com/Pickupwin/p/9156323.html
Copyright © 2011-2022 走看看