HDOJ 4650: Minimum Average Weight Path
来源:互联网 发布:千里眼软件 编辑:程序博客网 时间:2024/05/14 16:47
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4650
题目大意:
给定一个无重边的有向图,
求全源最小平均权值路径。
最小平均权值路径的定义是,路径总权值 / 路径上的边数最小。
算法:
题目应当分为两种情况:
两点间的路径上可能存在负环,如果一条路径沿着这个负环不断走下去,那么最终的平均值一定是趋于这个负环的平均权值。
无负环,那么这个显然很好求。
做这道题首先要知道一种用矩阵求两点间恰好K条边的最短路径的方法。不清楚的话建议去做POJ 3613。
首先,利用矩阵乘法,由1~n枚举路径长度,然后根据此时各点间的最短路 / 路径长度,不断更新此时的最小平均权值路径。
然后,讨论图上的各个环,如果某点有负环,那么对于任两个可以到达这个点的点对,这个负环的平均权值可能会更新这个点对上的最小平均权值。
PS:这算是我做过的少有的,在赛场上写出来且代码量极小,却可以把它归为中高级图论的题吧。笑。
代码如下:
#include<cstdio>#include<iostream>#include<algorithm>#include<sstream>#include<cstdlib>#include<cstring>#include<string>#include<climits>#include<cmath>#include<queue>#include<vector>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define eps 1e-8using namespace std;const int MAXN=110;int vis[MAXN][MAXN];double ans[MAXN][MAXN];int tot;struct Matrix{ int h,w; int mx[MAXN][MAXN]; Matrix operator* (const Matrix& b) const { Matrix tmp; memset(tmp.mx,INF,sizeof(tmp.mx)); tmp.h=h; tmp.w=b.w; for (int i=1; i<=h; i++) { for (int j=1; j<=b.w; j++) { for (int k=1; k<=w; k++) { if(vis[i][k]==-1||tot<vis[i][k]) { continue; } if(vis[k][j]==-1||tot<vis[k][j]) { continue; } tmp.mx[i][j]=min(tmp.mx[i][j],mx[i][k]+b.mx[k][j]); } } } return tmp; }};Matrix g,f;int main(){ int n, m; while(scanf("%d %d",&n, &m)==2) { memset(g.mx,INF,sizeof(g.mx)); g.h=g.w=n; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { ans[i][j]=1e7; } } memset(vis,-1,sizeof(vis)); for(int i=0; i<m; i++) { int u,v; scanf("%d%d",&u,&v); scanf("%d",&g.mx[u][v]); vis[u][v]=1; } for(int k=1; k<=n; k++) { for(int i=1; i<=n; i++) { if(vis[i][k]==-1) { continue; } for(int j=1; j<=n; j++) { if(vis[k][j]==-1) { continue; } vis[i][j]=(vis[i][j]==-1)?vis[i][k]+vis[k][j]:min(vis[i][j],vis[i][k]+vis[k][j]); } } } f=g; for(tot=1; tot<=n; tot++) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(vis[i][j]!=-1&&tot>=vis[i][j]) { ans[i][j]=min(ans[i][j],(double)f.mx[i][j]/tot); } } } f=f*g; } for(int k=1; k<=n; k++) { for(int i=1; i<=n; i++) { if(vis[i][k]==-1) { continue; } for(int j=1; j<=n; j++) { if(vis[k][j]==-1||vis[k][k]==-1) { continue; } ans[i][j]=min(ans[i][j],ans[k][k]); } } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(j>1) { putchar(' '); } if(vis[i][j]!=-1) { printf("%.3lf",ans[i][j]); } else { printf("NO"); } } puts(""); } } return 0;}
- HDOJ 4650: Minimum Average Weight Path
- hdu 4650 Minimum Average Weight Path
- hdu 4650 Minimum Average Weight Path
- hdu 4650 Minimum Average Weight Path(最短路,5级)
- 1000. Minimum Weight
- UVa 10560 Minimum Weight
- Minimum Average Waiting Time
- Path of Equal Weight
- HDOJ 5353 Average 模拟
- UVA 10560 - Minimum Weight(数论)
- uva 10560 - Minimum Weight(数论)
- 1053. Path of Equal Weight
- 1053. Path of Equal Weight
- PAT_1053: Path of Equal Weight
- 1053. Path of Equal Weight
- 1053. Path of Equal Weight
- 1053.Path of Equal Weight
- 1053. Path of Equal Weight
- 比较完美的SqlHelper类
- ping命令执行过程详解
- 笔记:Linux vi编辑器
- 黑马程序员—常用String类和StringBuffer
- FZOJ2110: Star
- HDOJ 4650: Minimum Average Weight Path
- JavaWeb的MyEclipse快速开发技巧:搜索
- HTTPClient和URLConnection核心区别分析
- linux中用户、用户组与文件权限
- linux系统移植要点
- 《JAVA与模式》学习计划
- AndroidManifest.xml配置文件各个知识点详解
- Seven Databases in Seven Weeks(七周七数据库)——PostgreSQL
- UVA 11039 - Building designing 水题哇~