标签:路径 for splay 复制 efi ack names space 存在
给出一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。
输入格式:
第一行包括2个整数N和M。
以下M行,每行三个数字A、B、W,表示从A到B有一条权值为W的有向边。
再下一行有一个整数Q。
以下Q行,每行一个询问X和Y,如题意所诉。
输出格式:
对于每个询问输出一行,表示该询问的最小密度路径的密度(保留3位小数),如果不存在这么一条路径输出“OMG!”(不含引号)。
3 3 1 3 5 2 1 6 2 3 6 2 1 3 2 3
5.000 5.500
主要是有一个除数很难处理
看了大佬的题解才发现
可以对floyed加一层边数
这样问题就解决了
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f const int N=100; const int M=4e6+54; int dp[N][N][11*N],n,m,a,b,c,q; double ans,minn; int main() { RII(n,m); rep(i,1,n)rep(j,1,n)rep(k,1,m)dp[i][j][k]=inf; rep(i,1,m) { RIII(a,b,c);if(c<dp[a][b][1])dp[a][b][1]=c; } rep(l,2,m) rep(k,1,n) rep(i,1,n) rep(j,1,n) dp[i][j][l]=min(dp[i][j][l],dp[i][k][l-1]+dp[k][j][1]); RI(q); rep(i,1,q) { RII(a,b); ans=inf; rep(l,1,m) { if(dp[a][b][l]!=inf) ans=min(ans,(double)dp[a][b][l]/(double)l ); } if(ans!=inf)printf("%.3lf\n",ans); else cout<<"OMG!"<<endl; } return 0; }
标签:路径 for splay 复制 efi ack names space 存在
原文地址:https://www.cnblogs.com/bxd123/p/10958859.html