CCF12.2行车路线(80分)

#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几行的代码用简单的优化方法,优化了。很开心。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值