您的位置:首页 > 其它

ZOJ 1456 / HDOJ 1385 -- Minimum Transport Cost (FLoyd+路径字典序)

2012-08-09 20:51 549 查看
之前尝试用 Dijkstra 写,但是回溯部分不会写,无奈之下网上找了一下别人的解题报告,发现竟然是用 Floyd 写的,我接触 Floyd 不太深入,于是在做这道题目的时候,我重新回顾了 Floyd 算法,思考其核心思想

预处理:约定 edge 保存输入数据的边权值,tax 保存站点的费用,ss,tt 分别记录当前的 起点 和 终点,那么可以这样构图,对于 ss 和 tt,显然这两点是不需要 tax 的,那么dist 数据记录 ss 到 当前点 k 的总费用,即 dist[ i ][ j ] = edge[ i ][ j ] + tax[ j ] (edge[ i ][ j ]!=0,edge[ i ][ j ]!=INF,j!=ss,j!=tt)

代码如下:

View Code

/*
PROG:   Minimum Transport Cost
ID  :   ouyangyewei
LANG:   C++
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory.h>
#include <algorithm>

const int maxn = 36;
const int INF = 0x3F3F3F3F;

int  N, EndPoint, tax[maxn], edge[maxn][maxn];
int  path[maxn][maxn], dist[maxn][maxn];

void ReadData()
{
int i, j;
for ( i=1; i<=N; ++i )
{
for ( j=1; j<=N; ++j )
scanf("%d", &edge[i][j]);
}// graph
for ( i=1; i<=N; ++i )
scanf("%d", &tax[i]);
}// ReadData

void Initalize( int src, int dest )
{
for ( int i=1; i<=N; ++i )
{
for ( int j=1; j<=N; ++j )
{
path[i][j] = j;
if ( j!=src && j!=dest && edge[i][j]!=0 && edge[i][j]!=-1 )
dist[i][j] = edge[i][j]+tax[j];
else
dist[i][j] = ( edge[i][j]==-1 ) ? INF:edge[i][j];
}
}// End of for

/*
for ( int i=1; i<=N; ++i )
{
for ( int j=1; j<=N; ++j )
printf("%10d ", dist[i][j]);
printf("\n");
}
printf("\n");
*/

}// Initalize

void Floyd( int src )
{
for ( int k=1; k<=N; ++k )
{
for ( int i=1; i<=N; ++i )
{
for ( int j=1; j<=N; ++j )
{
if ( k==i || k==j )    continue;

int tt = dist[i][k]+dist[k][j];
if ( tt<dist[i][j] )
dist[i][j] = tt, path[i][j] = path[i][k];
else if ( tt==dist[i][j] && path[i][j]>path[i][k] )
path[i][j] = path[i][k];
}
}
}// Loop
}// Floyd
/*
void dfs( int ss, int tt )
{
if ( tt!=ss )
dfs( ss, path[ss][tt] );

if ( tt!=EndPoint )
printf("%d-->", tt);
}// dfs
*/
void output( int src, int dest )
{
printf("From %d to %d :\nPath: %d", src, dest, src);

int t = src;
while ( t!=dest )
{
printf("-->%d", path[t][dest]);
t = path[t][dest];
}

printf("\nTotal cost : %d\n\n", dist[src][dest]);
}// output

void Solve()
{
int ss, tt;
while ( ~scanf("%d %d", &ss, &tt), ss+tt!=-2 )
{
Initalize( ss, tt );
Floyd( ss );
output( ss, tt );
}// start point and destination
}// Solve

int main()
{
while ( ~scanf("%d", &N), N!=0 )
{
ReadData();
Solve();
}// End of while

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: