poj 3268 强大的转置矩阵+两次Dijkstra(类似于求最大路)

题目链接:http://poj.org/problem?id=3268

题目大意,在有向图中,所有点到给定的点一来回所花时间的最小值。刚看到这题第一个想法floyd,不过马上意识到肯定超时,1000^3的复杂度是不能接受的,就想可以以给定点为源点使用Dijkstra这样可以求出所有点回来的路,但是所有点去的路怎么求,想到了搜索(类似于枚举)但这样视乎是不可能的。就想到了可以把所有点去给定点的单向路我们把反过来所花时间大小不变,这样所有点到给定点的距离不就变成了给定点到所有的点的距离,通过转置矩阵正好可以满足需求,同时可以重复的利用Dijkstra函数的接口,最后在所有点所花时间中取最大值即可。

 

View Code
#include<iostream>
#include
<cstring>
#include
<cstdio>
using namespace std;
const int INF=1005;
const int NK=10000000;
int map[INF][INF],vist[INF],dist[INF];
int map1[INF][INF],dist1[INF];
int n,m,k;
void Dijkstra()
{
int i,j,v,mi;
for (i=1;i<=n;i++)
{
dist[i]
=map[k][i];
}
vist[k]
=1;
dist[k]
=0;
for (i=1;i<n;i++)
{
mi
=NK;
for (j=1;j<=n;j++)
if(!vist[j]&&dist[j]<mi)
{
mi
=dist[j];
v
=j;
}
vist[v]
=1;
for (j=1;j<=n;j++)
if(!vist[j]&&dist[j]>dist[v]+map[v][j])
dist[j]
=dist[v]+map[v][j];
}
}
int main()
{
int i,j,mi,x,y,z;
while (cin>>n>>m>>k)
{
for (i=1;i<=n;i++)
{
vist[i]
=0;
for(j=1;j<=n;j++)
{
map[i][j]
=map1[i][j]=NK;
if(i==j)map[i][j]=map1[i][j]=0;
}
}

for (i=1;i<=m;i++)
{
cin
>>x>>y>>z;
map[x][y]
=z;
map1[x][y]
=z;
}
Dijkstra();
for (i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
dist1[i]
=dist[i];
map[j][i]
=map1[i][j];
vist[i]
=0;
}
Dijkstra();
mi
=0;
for (i=1;i<=n;i++)
{
dist[i]
+=dist1[i];
if(dist[i]>mi)mi=dist[i];
}
cout
<<mi<<endl;
}

return 0;
}
posted @ 2011-08-23 17:02  我们一直在努力  阅读(254)  评论(0编辑  收藏  举报