The Shortest Path
Time Limit: 1000MS Memory Limit: 20000K
Description:
某一个国家有 T (1 ≤ T ≤ 2,500) 个城市,编号分别是从1 到 T。除了起点和终点以外的每个城市, 都至少连接另外的两个城市(通过无向的道路连接)。
给一幅地图,其中有C (1 ≤ C ≤ 6,200) 条道路,道路的两端分别为 R1i 和 R2i (1 ≤R1i ≤ T; 1 ≤ R2i ≤ T) ,R1i 和 R2i之间的道路长度为 Ci (1 ≤ Ci ≤1,000)。请寻找由起点城市Ts (1 ≤ Ts ≤ T)到终点城市Te (1 ≤ Te ≤ T)的最近路径。
Input:
首先输入整数m,表示m种测试情况。接下来是每种测试情况的输入数据。
每种测试情况包含几行:
第一行包括4个整数T、C、Ts、Te,含义如上所述。
第2到C+1行中,第i+1行输入3个整数,分别表示第i条边的R1i 和 R2i和Ci。
Output:
对于每种情况输出一行,每行一个整数序列,表示该种情况的图中Ts到Te的最短路径。(保证每种情况一定能找到这样的路径)。
Sample Input:
1
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1
Sample Output:
5 6 1 4
Hint:
输入中可能存在重边的情况。
#include <iostream>
using namespace std;
#define INFINITY 10001
#define VISITED true
#define UNVISITED false
class Graph
{
private:
int V;
int E;
short int **G;
bool *mark;
public:
Graph(int vertex,int edge)
{
V=vertex; E=edge;
G=new short*[V]; //new an adjcent matrix
for(int i=0;i<V;i++)
G[i]=new short[V];
for(int i=0;i<V;i++) //initialization
for(int j=0;j<V;j++)
G[i][j]=INFINITY;
for(int i=0;i<V;++i)
G[i][i]=0;
mark=new bool[V];
for(int i=0;i<V;i++)
mark[i]=UNVISITED;
}
~Graph()
{
delete[] mark;
for(int i=0;i<V;++i)
delete[] G[i];
delete[]G;
}
short int v()
{return V;}
short int e()
{return E;}
void addEdge(short int Va,short int Vb,short int weight)
{
if(G[Va][Vb]>weight)
G[Va][Vb]=weight;
}
void setMark(short int v,bool VISIT)
{mark[v]=VISIT;}
bool getMark(short int v)
{return mark[v];}
short int first(int v)
{
int i;
for(i=0;i<V;++i)
if(G[v][i]<INFINITY)
return i;
return i;
}
int getWeight(short int v,short int j)
{return G[v][j];}
short int next(int v,int j)
{int i;
for( i=j+1;i<V;i++)
{
if(G[v][i]<INFINITY)
return i;
}
return i;
}
};
int minVertex(Graph* G,short int * Dis)
{
int i,v;
for(i=0;i<G->v();++i)
if(G->getMark(i)==UNVISITED)
{v=i;break;}
for(++i;i<G->v();++i)
if(G->getMark(i)==UNVISITED&&(Dis[i]<Dis[v]))
v=i;
return v;
}
void Dijkstra(Graph* G,int from,int to,short int *Path)
{
short int *Dis=new short int[G->v()];
for(int i=0;i<G->v();++i)
Dis[i]=INFINITY;
Dis[from]=0;
for(int i=0;i<G->v();i++)
{
int v=minVertex(G,Dis);
//if(Dis[v]==INFINITY){cout<<"wrong input."<<v<<endl;for(int i2=0;i2<G->v();++i2)cout<<Dis[i2]<<' ';return;}
G->setMark(v,VISITED);
//if(v=to) return;
for(int j=G->first(v);j<G->v();j=G->next(v,j))
if(Dis[j]>(Dis[v]+G->getWeight(v,j)))
{
Dis[j]=Dis[v]+G->getWeight(v,j);
Path[j]=v;
}
}
//for(int i=0;i<G->v();i++) cout<<Path[i]<<' ';cout<<endl;
delete [] Dis;
}
void showPathHelp(short int*Path,int from,int to)
{ if(from==to){cout<<from+1<<' ';return;}
if(Path[to]==from) {cout<<from+1<<' '<<to+1<<' ';return;}
showPathHelp(Path,from,Path[to]);
cout<<to+1<<' ';
return;
}
void showPath(short int*Path,int from,int to)
{
showPathHelp(Path,from,Path[to]);
if(to!=from)
cout<<to+1<<endl;
else
cout<<endl;
}
int main()
{
int testNum;
cin>>testNum;
for(int i=0;i<testNum;i++)
{
int V,E,from,to;
cin>>V>>E>>from>>to;
--from;--to;
Graph* G=new Graph(V,E);
for(int j=0;j<E;++j)
{
int u,v,w;
cin>>u>>v>>w;
--u;--v;
G->addEdge(u,v, w);
G->addEdge(v,u, w);
}
short int *Path=new short int[G->v()];
for(int j=0;j<G->v();++j)
Path[j]=-1;
Path[from]=from;
Dijkstra(G,from,to,Path);
showPath(Path,from,to);
delete []Path;
G->~Graph();
}
return 0;
}