sicily 1031(week 5)

来源:互联网 发布:店铺淘宝客sina 编辑:程序博客网 时间:2024/05/17 22:11

题目链接:http://soj.me/1031

题目大意:

给出四个校区的一些地点之间的距离,地点名用字符串来表示,问某两个地点之间的最短路径长度,典型的单源最短路径题目

思路:

单源最短路径问题可以用dijkstra算法实现,这道题比较麻烦的是用字符串来表示地点,我用的处理方法是建立map得到地点名字到序号的映射,对于每个新输入的地点名字,先在map里面查找是否存在,如果不存在就绑定一个新的序号.地点之间的距离用邻接矩阵来存放 题目:sicily1031(单源最短路径),注意一共最多可能有100个节点,最大路径,最大可以去到100*100=10000

#include<iostream>#include<string>#include<map>#include<memory.h>using namespace std;#define MAX 250int djstra(int a[][MAX],int snode,int tnode,int  nodelen){    bool visit[MAX];    int dist[MAX];    memset(visit, false, sizeof(visit));    for(int i = 0;i<250;i++)    dist[i] = 100000;    dist[snode] = 0;    visit[snode]=true;    for (int i = 0; i < nodelen; i++){        //  寻找最短路径(s,t),同时把t加入S集合        int min =100000;        int min_j =snode;        for(int j = 0; j < nodelen; j++){            if (!visit[j] && dist[j] < min)  {                min = dist[j];//记录最小值和最小值的下标                min_j = j ;            }        }        visit[min_j] = true;        //  松弛边(t,v),其中v为顶点        for(int k = 0; k < nodelen; k++){            if (!visit[k] && dist[k]>dist[min_j]+a[min_j][k] )                dist[k] = dist[min_j]+a[min_j][k];        }    }    // 非连通图    if(!visit[tnode])        return -1;    // 连通图    else{        return dist[tnode];    }};int main() {    int c;    //测试用例数目    cin>>c;    while(c--){        int a[MAX][MAX];        for(int i = 0;i<250;i++)            for(int j = 0;j<250;j++){                a[i][j] = 100000;                if(i==j)                a[i][j]=0;            }        map<string,int> mymap;        int n;        string snode,tnode;        cin>>n;        //总的node数目        int i = 0;        while(n--){            string s,t;            int d,si,ti;            cin>>s>>t>>d;            // 字符串到整数数组的映射            if(mymap.find(s)==mymap.end()){                mymap[s] = i;                si = i;                i++;            }            else{                si = mymap[s];            }            if(mymap.find(t)==mymap.end()){                mymap[t] = i;                ti = i;                i++;            }            else{                ti = mymap[t];            }            a[si][ti] = d;            a[ti][si] = d;        }        cin>>snode>>tnode;        // 起点等于终点        if(tnode==snode)            cout<<"0"<<endl;        else         // 起点或者终点不存在        if(!mymap.count(snode)||!mymap.count(tnode))            cout<<"-1"<<endl;        else        cout<<djstra(a, mymap[snode], mymap[tnode],i)<<endl;    }}                                 

总结

dijstra算法模板:

dijkstra的过程初始将顶点s加入到S中,并更新s到其他顶点的路径权值。选择最短路径dist(s,t),并将t加入到S中。在第一步中得到t,对于u∈V-S,松弛边(t,v)。重复上述过程,直到所有的顶点都被加入到集合S中为止。可以给出伪代码://  初始化for i=[0,n)    dist[i] = tab[0][i]visit[0] = true;for i=[1,n)    //  寻找最短路径(s,t),同时把t加入S集合    min = MAX_VALUE    for j=[0,n)        if !visit[j] && dist[j]<min            min = dist[j]    visit[j] = true    //  松弛边(t,v),其中v为顶点    for k=[0,n)        if !visit[k] && dist[k]>dist[j]+tab[j][k]            dist[k] = dist[j]+tab[j][k]
0 0