hdu 1680——Choose the best route dijkstra算法

来源:互联网 发布:数据库监控 编辑:程序博客网 时间:2024/05/07 05:44

点击打开链接hdu 1680 

题意:kiki家附近有多个车站,给出终点站,两个车站尖的花费 求最短花费

分析:起点有多个可供选择,一个终点 两种方法,一:超级源点;二:从终点逆推。

法一:超级源点

#include <stdio.h>#include <string.h>int map[1005][1005];int dis[1005];bool flag[1005];int main(){    int n,m,s,i,j,k,p,q,t,w,tem;    while(scanf("%d%d%d",&n,&m,&s) != EOF)    {        for(i = 0; i < 1005; i++)            for(j = 0; j < 1005; j++)                    map[i][j] = 1000000;        while(m--)        {            scanf("%d%d%d",&p,&q,&t);            if(t < map[p][q])//多条路经                map[p][q] = t;        }        scanf("%d",&w);        while(w--)        {            scanf("%d",&tem);            map[0][tem] = 0;//‘0’为所加的超级源点,令所有起点到0点的距离为0,其余点无穷大,在迪杰斯特拉算法中 最先找出这些起点 逐步更新。        }        memset(flag,0,sizeof(flag));        dis[0]=0;        for(int i = 1; i <= n; i++)            dis[i] = 1000000;        int ok=0,t,minn;        for(int i = 0; i <= n; i++) //迪杰斯特拉算法核心        {            minn = 1000000;            for(int j = 0; j <= n; j++)                 if(!flag[j] && dis[j] < minn)                    minn = dis[j],t = j;            flag[t] = 1;            if(t == s)            {                ok=1;                break;            }            for(int j = 1; j <= n; j++)                 if(!flag[j] && dis[t] + map[t][j] < dis[j])                    dis[j] = dis[t] + map[t][j];        }        if(ok==1)            printf("%d\n",dis[t]);        else            printf("-1\n");    }    return 0;}
法二:逆推

#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAX 0x3f3f3f3f#define N 1010int num, road, destination;int map[N][N], dis[N], oppo[N];bool visit[N];void Dijkstra(int start){    int temp, k;    memset(visit, 0, sizeof(visit));    for(int i = 1; i <= num; ++i)         dis[i] = map[start][i];dis[start] = 0;visit[start] = 1;    for(int i = 1; i <= num; ++i)    {        temp = MAX;        for(int j = 1; j <= num; ++j)            if(!visit[j] && temp > dis[j])                temp = dis[k = j];        if(temp == MAX) break;        visit[k] = 1;        for(int j = 1; j <= num; ++j)            if(!visit[j] && dis[j] > dis[k] + map[k][j])                dis[j] = dis[k] + map[k][j];    }}int main(){    int x, y, cost, exp, minn;    while(scanf("%d%d%d", &num, &road, &destination) != EOF)    {        memset(map, MAX, sizeof(map));        for(int i = 1; i <= road; ++i)        {            scanf("%d%d%d", &x, &y, &cost);if(cost < map[y][x]) //巧妙之处:反向图            map[y][x] = cost;        }        scanf("%d", &exp);        for(int i = 1; i <= exp; ++i)            scanf("%d", &oppo[i]);        Dijkstra(destination);minn = MAX;for(int i = 1; i <= exp; ++i) //起点找到终点最小值if(dis[oppo[i]] < minn)minn = dis[oppo[i]];        if(minn == MAX) printf("-1\n");        else printf("%d\n", minn);    }    return 0;}



0 0
原创粉丝点击