二维数组和vector实现dijkstra

来源:互联网 发布:上海软件项目经理工资 编辑:程序博客网 时间:2024/06/06 12:41

关于迪杰斯特拉算法:通俗的来讲就是每次从起点(确定、唯一)选一条到终点(此处终点是广义的终点不是题目所给出询问的终点)最短的路(dist[i])(dist[i]是一边使用 一边修改的注意!)将该终点作为行营,依次向外扩展,更新从起点到这点的最短路。(二维数组:对于行营接触不到的点本来是想更新的,但由于if判断语句不为真所以没更新成,定义域为全体的点;vector:由于vector形象的存放了与当前点相连的点 ,因此只是想更新与当前点相连的点,定义域比二维数组的要小 //for(j=0; j

int vis[MAXN];int dist[205];struct Edge{    int des;    int value;};vector<Edge>roadd[MAXN];int dijkstra(int st,int en,int n){    int i,j,flag;    memset(vis,0,sizeof(vis));    for(i=1;i<=MAXN;i++)        dist[i]=INF;    vis[st]=1;    dist[0]=9999;   //以便于求解路里面最短的那条                     //既然我们存路是从1开始存的 那么我们可以用0来干一点别的事 /奸笑 这个数的设置视情况而定    dist[st]=0;    int cur=st;//第一次跑i的循环的时候从st开始 此后就不是了    for(i=1;i<=n;i++){        for(j=0;j<roadd[cur].size();j++){   //这里的循环一定要从0开始跑 因为vector的第二维下标是从0开始的             int tempend=roadd[cur][j].des; //temp_end为与当前cur点相连的点(roadd[cur][j])的...就叫他名称吧(区分于权值)不知道怎么表达             if(dist[cur]+roadd[cur][j].value<dist[tempend])//这里其实不用写&&!vis[cur] 第一遍i的循环cur是手动赋的值为st                                                     //此后的cur都是在前一遍循环末尾求出来的 在求这个值的时候已经判断过了                 dist[tempend]=dist[cur]+roadd[cur][j].value;        }        cur=0;        for(j=1;j<=n;j++){            if(dist[j]<dist[cur]&&!vis[j]){                cur=j;      //找一条最短路 当跑完第一遍循环的时候 cur是与st相连的点中路径最短的那个点 下一次循环的时候用【起点到cur点的距离加上(cur点)到(与cur相连的点)的距离】与【起点到与cur相连的点的距离】进行比较并更新 依次循环 当把所有点都cur一遍之后就可以得到最短路径            }        }         vis[cur]=1;    }       return dist[en];}//妈呀好难呀int main(){    int n,m;        //n为节点数(1-n),m为路的条数     Edge temp;    int i,j;    int st,en,len,asken,askst;    while(cin>>n>>m&&n&&m){        for(i=0;i<=n;i++)            roadd[i].clear(); //多组数据的时候一定记得去掉上次数据中保留下来的路的连通状态        for(i=1;i<=m;i++){            cin>>st>>en>>len;            temp.des=en;            temp.value=len;            roadd[st].push_back(temp);            temp.des=st;            roadd[en].push_back(temp);//双向路         }        cin>>askst>>asken; //询问         cout<<dijkstra(askst,asken,n)<<endl;    }    return 0;}

二维数组:

int dist[MAXN];int map[MAXN][MAXN];int vis[MAXN];int dijkstra(int st,int end,int n){    int i,j,flag;    memset(vis,0,sizeof(vis));    for(i=1;i<=n;i++)    if(i==st) dist[i]=0;    else         dist[i]=map[st][i];    vis[st]=1;    for(i=1;i<n;i++){        int mmin=INF;flag=0;        for(j=1;j<=n;j++){            if(dist[j]<mmin&&!vis[j]){                mmin=dist[j];                flag=j;            }        }        vis[flag]=1;        for(j=1;j<=n;j++)            if(dist[j]>dist[flag]+map[flag][j]&&!vis[j])                dist[j]=dist[flag]+map[flag][j];                }}int main(){    int n,m,i,j;    int st,en;    int sour,des,len;    while(cin>>n>>m){        for(i=1;i<=n;i++)            for(j=1;j<=n;j++){                i==j? map[i][j]=0:map[i][j]=INF; //初始化数组 认为所有的路都不连通             }        for(i=1;i<=m;i++){            cin>>sour>>des>>len;            if(len<map[sour][des]){                map[sour][des]=map[des][sour]=len; //若两条路连通 将其距离修改             }        }           cin>>st>>en; //询问         cout<<dijkstra(st,en,n)<<endl;                                  }    return 0;}