zoukankan      html  css  js  c++  java
  • 【洛谷P1730】最小密度路径

    题目大意:给定一个 N 个点,M 条边的有向图,现有 Q 个询问,每次询问 X 到 Y 的最小密度路径是多少。最小密度路径的定义是路径长度除以路径边数。

    题解:利用矩阵乘法,可以预处理出从 X 到 Y 恰好经过 K 条边的最短路是多少。对于每次询问,直接处理处理即可,时间复杂度为 (O(n^4))

    注意:恰好经过 K 条边的最短路不能将 G[i][i] 初始化成 0,因为边数有实际意义,若这样初始化意味着有自环出现。至少经过 K 条边的同理,也不能这样初始化。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=55;
    const int inf=0x3f3f3f3f;
    
    int n,m,q;
    struct mat{
    	int d[maxn][maxn];
    	mat(){memset(d,0x3f,sizeof(d));}
    	int *operator[](int i){return d[i];}
    	friend mat operator*(mat &x,mat &y){
    		mat z;
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=n;j++)
    				for(int k=1;k<=n;k++)
    					z[i][j]=min(z[i][j],x[i][k]+y[k][j]);
    		return z;
    	}
    }d[maxn];
    
    void read_and_parse(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		int x,y,z;scanf("%d%d%d",&x,&y,&z);
    		d[1][x][y]=min(d[1][x][y],z);
    	}
    }
    void solve(){
    	for(int i=2;i<=n;i++)d[i]=d[i-1]*d[1];
    	scanf("%d",&q);
    	while(q--){
    		int x,y;scanf("%d%d",&x,&y);
    		bool flag=0;double ans=1e18;
    		for(int i=n;i;i--){
    			if(d[i][x][y]!=inf){
    				flag=1;
    				ans=min(ans,(double)d[i][x][y]/(double)i);
    			}
    		}
    		if(flag)printf("%.3lf
    ",ans);
    		else puts("OMG!");
    	}
    }
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    反射 元类
    多态
    封装
    继承
    面向基础
    包 logging模块 hashlib模块 openpyxl 深浅拷贝
    常用模块
    re模块(正则表达式)
    模块 导入方式 软件开发目录规范
    第 3 章 镜像
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10818836.html
Copyright © 2011-2022 走看看