dijkstra模板

/*dijkstra用于有权图,权值非负,起点终点已知,算法运行过程不断维护的关键信息是节点集合s。从源点(初始点)开始将路径最小的点u加入到集合s,不断重复该过程,终止条件是终点纳入集合s,他是贪心的策略但是正确的具体证明见算法导论第三版p385*/  
/*题意为从1~n的最短路径*/  
/*此题的坑主要是两点之间可能有重边在主函数中已解决详情见代码*/  
 #include<cstdio>    
 #include<cstring>    
 #include<algorithm>  
 #include<iostream>    
 using namespace std;  
 const int INF=99999999;     
 int maps[1005][1005],v[1005],d[1005]; //v表示节点是(1)否(0)已纳入集合 | d表示当前这个集合最小值    
 int n;  
 void Dijkstra(int s,int t)  
 {  
     int i,j,k,mini;  
     for(i=1;i<=n;i++) d[i]=INF;   
     d[s]=0;    //只有初始点的集合当然最小值为0   
     for(i=1;i<=n;i++)     //该层循环是为了说明从起始点查找到终点的最短路径最多查找n个节点即查找次数(不用在意)   
     {                                                   
        mini=INF;  
        k=-1;   //纳入集合的将被标记,k为下标   
        for(j=1;j<=n;j++)    //该层循环目的是 获得前驱节点的最小值并将前驱节点标记加入集合   
        {  
            if(!v[j] && d[j]<mini)      
            {  
                k = j;  
                mini = d[k];  
            }  
        }  
        v[k]=1;  
        if(k==t)    //判断若终点t已经被标记为k,说明已经将重点纳入集合那么终止查找最短路   
        {  
            printf("%d\n",d[t]);  
            return;  
        }     
        for(j=1;j<=n;j++)     //改成for循环的目的 寻找可纳入集合的下一个点   
        {  
            if(!v[j] && d[k]+maps[k][j]<d[j])    //前驱节点所在的结合d[k]向可纳入的下一个点的集合 d[k]+maps[k][j]的更新   
            {   
                d[j]=d[k]+maps[k][j];  
            }  
        }     
    }  
 }  
   
 void init()  
 {  
    memset(v,0,sizeof(v)); //清除标记   
    for(int i=1;i<=n;i++)  
    {  
        for(int j=1;j<=n;j++)  
        {  
            maps[i][j]=INF;  
        }  
    }  
 }  
   
  int main()  
 {  
    /*int T,i,j,x,y,D;  
    while(scanf("%d %d",&T,&n)!=EOF)  
        {  
            init();   
            for(i=1;i<=T;i++)  
            {  
                scanf("%d %d %d",&x,&y,&D);  
                if(maps[x][y]>D)     //这里一点要注意,两个点之间未必只有一条边这里目的  若有重边那么此时已经选择了最短的边   
                maps[x][y]=D,maps[y][x]=D;  
            }  
             Dijkstra(1,n);  
     }*/    
    return 0;  
 }  
 #include<cstdio>    
 #include<cstring>    
 #include<algorithm>  
 #include<iostream>    
 using namespace std;  
 const int INF=99999999;     
 int maps[1005][1005],v[1005],d[1005]; 
 int n;  
 void Dijkstra(int s,int t)  
 {  
     int i,j,k,mini;  
     for(i=1;i<=n;i++) d[i]=maps[s][i];//for(i=1;i<=n;i++) d[i]=INF;   
     //d[s]=0;      
     for(i=1;i<=n;i++)        
     {                                                   
        mini=INF;  
        k=-1;      
        for(j=1;j<=n;j++)      
        {  
            if(!v[j] && d[j]<mini)      
            {  
                k = j;  
                mini = d[k];  
            }  
        }  
        v[k]=1;  
        if(k==t)       
        {  
            printf("%d\n",d[t]);  
            return;  
        }     
        for(j=1;j<=n;j++)        
        {  
            if(!v[j] && d[k]+maps[k][j]<d[j])       
            {   
                d[j]=d[k]+maps[k][j];  
            }  
        }     
    }  
 }  
   
 void init()  
 {  
    memset(v,0,sizeof(v)); //清除标记   
    for(int i=1;i<=n;i++)  
    {  
        for(int j=1;j<=n;j++)  
        {  
            maps[i][j]=INF;maps[i][i]=0; 
        }  
    }  
 }  
   
  int main()  
 {  
    
    return 0;  
 }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值