#include <stdio.h>
#include <malloc.h>
#define true 1
#define false 0
#define MaxVerNum 500
#define INFINITY 10000000
struct Visite {
int Dist;
int Path;
int Known;
};
struct GraphStruct {
int vexnum, arcnum;
int Matrix[MaxVerNum][MaxVerNum];
};
typedef struct GraphStruct* Graph;
struct Visite Visited[MaxVerNum];
Graph createGraph();
void initializeGraph( Graph G );
void Dijkstra( Graph G, int u );
void initializeVisite( Graph G, int u );
int computeTired( Graph G, int v1, int v2 );
int findMinDist( Graph G );
int main( void ) {
int i = 0;
int v1, v2, hard, dist;
Graph G = createGraph();
for( i = 0; i < G->arcnum; i++ ) {
scanf("%d %d %d %d", &hard, &v1, &v2, &dist);
if( hard == 1 ) {
dist *= -1;
}
G->Matrix[v1-1][v2-1] = G->Matrix[v2-1][v1-1] = dist;
}
Dijkstra( G, 0 );
printf("%d", Visited[G->vexnum-1].Dist);
return 0;
}
Graph createGraph() {
Graph G = ( Graph )malloc( sizeof( struct GraphStruct) );
if( !G ) {
printf("Space Error");
return NULL;
}
initializeGraph( G );
return G;
}
void initializeGraph( Graph G ) {
scanf("%d %d", &G->vexnum, &G->arcnum);
int i = 0, j = 0;
for( i = 0; i < G->vexnum; i++ ) {
for( j = 0; j < G->vexnum; j++ ) {
G->Matrix[i][j] = INFINITY;
}
Visited[i].Known = false;
Visited[i].Dist = INFINITY;
Visited[i].Path = -1;
}
}
void initializeVisite( Graph G, int u ) {
Visited[u].Path = -1;//可能有错
Visited[u].Known = true;
Visited[u].Dist = 0;
int i = 0;
for( i = 0; i < G->vexnum; i++ ) {
if( G->Matrix[u][i] != INFINITY ) {
if( G->Matrix[u][i] < 0 ) {
Visited[i].Dist = G->Matrix[u][i] * G->Matrix[u][i];
}
else {
Visited[i].Dist = G->Matrix[u][i];
}
Visited[i].Path = u;
}
}
}
void Dijkstra( Graph G, int u ) {
initializeVisite( G, u );
int V = 0;
int i = 0;
int Tired = 0;
while( 1 ) {
V = findMinDist( G );
if( V == -1 ) {
break;
}
Visited[V].Known = true;
for( i = 0; i < G->vexnum; i++ ) {
if( G->Matrix[V][i] != INFINITY && !Visited[i].Known ) {
//开始更新
Tired = G->Matrix[V][i] < 0 ? computeTired( G, V, i ) : G->Matrix[V][i] + Visited[V].Dist;
if( Visited[i].Dist > Tired ) {
Visited[i].Dist = Tired;
Visited[i].Path = V;
}
}
}
}
}
int computeTired( Graph G, int v1, int v2 ) {
int sum = G->Matrix[v1][v2];
int p = Visited[v1].Path;
int lastV = v1;
while( p != -1 ) {
if( G->Matrix[p][lastV] > 0 ) {
break;
}
sum += G->Matrix[p][lastV];
lastV = p;
p = Visited[p].Path;
}
return sum*sum + Visited[lastV].Dist;
}
int findMinDist( Graph G ) {
int v = -1, i = 0;
int Min = INFINITY-10;
for( i = 0; i < G->vexnum; i++ ) {
if( !Visited[i].Known && Min > Visited[i].Dist ) {
Min = Visited[i].Dist;
v = i;
}
}
return v;
}
80分,错在哪还不知道。但中间有一段10几行的代码用简单的优化方法,优化了。很开心。
CCF12.2行车路线(80分)
最新推荐文章于 2021-09-05 20:36:14 发布