zoukankan      html  css  js  c++  java
  • 【ybtoj】【期望问题】路径长度

    题意

    image

    题解

    乍一看:这也太简单了,纯纯的水题啊!
    我原本的思路:(dis_i) 表示 (1)(i) 的期望距离,转移大致是 (dis_v+=(dis_v+1.0*w_i)/oud_v).
    后来发现不对:对于每一条路选择的概率要传递下去,于是又加上一个数组 (p_i) 表示走到 (i) 的概率。
    但是无法转移,简单的样例就足以说明一切。
    这种做法的问题在于无法求出一条完整路径的期望距离。
    看了题解拓宽思路:
    更改 (dis_i) 的定义,改为从 (i) 出发到 (n) 的路径期望长度,那么 (dis_i=(sum dis_j+w(i,j))/oud_i)
    同时反向建图跑拓扑,就可以避免这个问题。
    同时贴上正确代码和错误代码,方便比较区别。

    错误代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int INF = 0x3f3f3f3f,N = 1e5+10,M = N<<1;
    inline ll read()
    {
    	ll ret=0;char ch=' ',c=getchar();
    	while(!(c>='0'&&c<='9')) ch=c,c=getchar();
    	while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
    	return ch=='-'?-ret:ret;
    }
    int n,m;
    int ecnt=-1,head[N],oud[N],ind[N];
    double dis[N],p[N];
    struct edge
    {
    	int nxt,to,w; 
    }a[M];
    inline void add(int x,int y,int w)
    {
    	a[++ecnt]=(edge){head[x],y,w};
    	head[x]=ecnt; 
    }
    queue<int> q;
    void bfs()
    {
    	q.push(1);p[1]=1;
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=head[u];~i;i=a[i].nxt)
    		{
    			int v=a[i].to;
    			p[v]+=p[u]/oud[u];
    			dis[v]+=dis[u]+1.0*a[i].w*p[v]; 
    			ind[v]--;
    			if(!ind[v]) q.push(v); 
    		}
    		printf("u=%d,dis[%d]=%.2lf
    ",u,u,dis[u]);
    	}
    }
    int main()
    {
    	n=read(),m=read();
    	memset(head,-1,sizeof(head));
    	for(int i=1;i<=m;i++) 
    	{
    		int u=read(),v=read(),w=read();
    		add(u,v,w);
    		oud[u]++,ind[v]++;
    	}
    	bfs();
    	printf("%.2lf",dis[n]);
    	return 0;
    }
    

    正确代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int INF = 0x3f3f3f3f,N = 1e5+10,M = N<<1;
    inline ll read()
    {
    	ll ret=0;char ch=' ',c=getchar();
    	while(!(c>='0'&&c<='9')) ch=c,c=getchar();
    	while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
    	return ch=='-'?-ret:ret;
    }
    int n,m;
    int ecnt=-1,head[N],oud[N],ind[N];
    double dis[N];
    struct edge
    {
    	int nxt,to,w; 
    }a[M];
    inline void add(int x,int y,int w)
    {
    	a[++ecnt]=(edge){head[x],y,w};
    	head[x]=ecnt; 
    }
    queue<int> q;
    void bfs()
    {
    	q.push(n);
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=head[u];~i;i=a[i].nxt)
    		{
    			int v=a[i].to;
    			dis[v]+=(dis[u]+1.0*a[i].w)/oud[v]; 
    			ind[v]--;
    			if(!ind[v]) q.push(v); 
    		}
    		//printf("u=%d,dis[%d]=%.2lf
    ",u,u,dis[u]);
    	}
    }
    int main()
    {
    	n=read(),m=read();
    	memset(head,-1,sizeof(head));
    	for(int i=1;i<=m;i++) 
    	{
    		int u=read(),v=read(),w=read();
    		add(v,u,w);
    		oud[u]++,ind[u]++;
    	}
    	bfs();
    	printf("%.2lf",dis[1]);
    	return 0;
    }
    
  • 相关阅读:
    nodeJs-querystring 模块
    nodeJs-process对象
    nodejs-Path模块
    nodejs-os模块
    nodejs-CommonJS规范
    nodejs-Events模块
    nodejs-Http模块
    nodejs-Cluster模块
    转:AOP与JAVA动态代理
    转:jdk动态代理实现
  • 原文地址:https://www.cnblogs.com/conprour/p/15308907.html
Copyright © 2011-2022 走看看