|
|
| Minimum Average Weight Path Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description In mathematics, a graph is a representation of a set of objects where some pairs of the objects are connected by links. The interconnected objects are represented by mathematical abstractions called vertices, and the links that connect some pairs of vertices are called edges. A path in a graph is a sequence of vertices, and for any 2 adjacent u, v, there is a edge from u to v in graph. A path contains at least one edge. In the graph in Sample 2, {3, 3, 2, 2} can form a path from 3 to 2.
Input Muiltcases. The first line contains two integer n, m, (1 ≤ n ≤ 102, 1 ≤ m ≤ 104 ) the number of the vertices and the number of the edges.
Output A n × n matrix representing the APMAWP. The j's element of the i's row represents the minimum average weight of all the paths from vertex i to vertex j. If no such path exists, you need to output "NO" instead (DO NOT output quote please). For each real number, you need to keep exactly 3 digits after digit point.
Sample Input 4 4 2 1 2 1 3 -8 2 4 -6 4 3 1 5 8 3 3 735 2 1 946 4 2 276 2 2 -990 3 2 -162 4 4 -18 3 5 783 5 5 -156
Sample Output NO NO -8.000 NO 2.000 NO -3.000 -6.000 NO NO NO NO NO NO 1.000 NO NO NO NO NO NO -990.000 -990.000 NO NO NO -990.000 -990.000 735.000 NO -156.000 -990.000 -990.000 NO -18.000 NO NO NO NO NO -156.000
Source 2013 Multi-University Training Contest 5
Recommend zhuyuanchen52 |
思路:全源最短路,求平均边权最小,这个还是比较简单的,当时怎么没去看这题呢?
#include<iostream>
#include<cstring>
#include<cstdio>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define clr(f,z) memset(f,z,sizeof(f))
using namespace std;
const int mm=103;
const int oo=0x3f3f3f;
int g[mm][mm],fg[mm][mm],t[mm][mm];
int vis[mm][mm];//过几条边相见
double ans[mm][mm];
int n,m;
void acopy(int(*a)[mm],int(*b)[mm])
{
FOR(i,1,n)FOR(j,1,n)a[i][j]=b[i][j];
}
void mul(int(*a)[mm],int(*b)[mm],int lol)
{ acopy(t,a);FOR(i,1,n)FOR(j,1,n)a[i][j]=oo;
FOR(i,1,n)FOR(j,1,n)FOR(k,1,n)
{
if(vis[i][k]==-1||lol<vis[i][k])continue;
if(vis[k][j]==-1||lol<vis[k][j])continue;
a[i][j]=min(a[i][j],t[i][k]+b[k][j]);
}
}
void debug(int(*a)[mm])
{ puts("+++++++++++++++++++++++");
FOR(i,1,n)FOR(j,1,n)
{
printf("%d ",a[i][j]);
if(j==n)puts("");
}
puts("+++++++++++++++++++++++++");
}
int main()
{ int a,b,c;
while(~scanf("%d%d",&n,&m))
{
FOR(i,1,n)FOR(j,1,n)ans[i][j]=oo;
clr(vis,-1);clr(g,0x3f);
FOR(i,1,m)
{
scanf("%d%d%d",&a,&b,&c);
g[a][b]=c;vis[a][b]=1;
}
FOR(k,1,n)FOR(i,1,n)if(vis[i][k]!=-1)
FOR(j,1,n)if(vis[k][j]!=-1)
{
vis[i][j]=vis[i][j]==-1?vis[i][k]+vis[k][j]:min(vis[i][j],vis[i][k]+vis[k][j]);
}///求出最少边相连
acopy(fg,g);
FOR(k,1,n){FOR(i,1,n)FOR(j,1,n)
if(vis[i][j]!=-1&&k>=vis[i][j])///边数需要大于等相遇最小边数
ans[i][j]=min(ans[i][j],(double)fg[i][j]/k);
mul(fg,g,k);//debug(fg);
}///K连边
FOR(k,1,n)FOR(i,1,n)if(vis[i][k]!=-1)FOR(j,1,n)
if(vis[k][j]!=-1&&vis[k][k]!=-1)
{
ans[i][j]=min(ans[i][j],ans[k][k]);
}
FOR(i,1,n)FOR(j,1,n)
{
if(j>1)putchar(' ');
if(vis[i][j]==-1)printf("NO");
else //cout<<ans[i][j];
printf("%.3lf",ans[i][j]);
if(j==n)printf("\n");
}
}
return 0;
}
全源最短路径平均边权问题
本文探讨了一个图论问题,即寻找图中所有顶点对之间的路径,使得这些路径的平均边权最小。文章提供了一种解决方法,并通过代码示例详细解释了实现过程。
514

被折叠的 条评论
为什么被折叠?



