Codevs 1557 热浪 解题报告

题目在这


热浪,一道中规中矩的最短路模版题,适合用来练手~


于是我分别用“邻接链表和SPFA”以及“邻接矩阵和dijstra”两种方法打了这道题,但实际方法还很多。

此外,我的代码写的有点个人化,不太适合看,希望有大牛能指点我一下代码方面的问题,感激不尽!


邻接链表和SPFA:

#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;

const int T=2500+5;
const int N=6200+5;

struct Edge{
   
  int fm,to,val;   
   
};

vector<Edge> v[N];

int t,c,ts,te;
int dis[T];
bool vis[T];
queue<int> q;

int main(){

    scanf("%d %d %d %d",&t,&c,&ts,&te); 
  
    for(int i=1;i<=c;i++){
    
        Edge edge;
        
        scanf("%d %d %d",&edge.fm,&edge.to,&edge.val);
        
        v[edge.fm].push_back(edge);
        
        swap(edge.fm,edge.to);
        
        v[edge.fm].push_back(edge);
    
    }   
    
    memset(dis,INF,sizeof(dis));
    memset(vis,false,sizeof(vis));
    dis[ts]=0;
    vis[ts]=true;
    q.push(ts);
    
    while( !q.empty()){ 
    
        int point=q.front();
        q.pop();
        vis[point]=false;
       
        for(int i=0;i<v[point].size();i++){
        
            int npoint=v[point][i].to;
            
            if ( v[point][i].val+dis[point]<dis[npoint] ){
            
                dis[npoint]=v[point][i].val+dis[point]; 
            
                if ( !vis[npoint] ) vis[npoint]=true,q.push(npoint);
            
            }    
                                                              
        }    
    
    }  
    
    printf("%d",dis[te]);  
   
  return 0;
  
}


邻接矩阵和dijstra:

#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;

const int T=2500+5;
const int N=6200+5;

int v[T][T];

int t,c,ts,te;
int dis[T];
bool vis[T];
vector<int> ex;

int main(){

    scanf("%d %d %d %d",&t,&c,&ts,&te); 
    
    memset(v,INF,sizeof(v));
    
    for(int i=1;i<=c;i++){
    
        int fm,to,val;
        
        scanf("%d %d %d",&fm,&to,&val);
        
        v[fm][to]=v[to][fm]=val;   
    
    }   
    
    memset(dis,INF,sizeof(dis));    
    memset(vis,false,sizeof(vis));
    dis[ts]=0;
    ex.push_back(ts); // 将起点添加至可扩展点的集合之中 
    
    
    while( !ex.empty() ){  // 当前扩展点不为空 
        
        int minn=INF,npoint,pos; 
        for(int i=0;i<ex.size();i++)         
          if ( dis[ex[i]]<minn ) npoint=ex[i],minn=dis[ex[i]],pos=i; // 记录最短路径 
        
        vis[npoint]=true; // 加入访问过的集合 
        ex.erase(ex.begin()+pos);  // 将其从可扩展点的集合除去 
                   
        for(int i=1;i<=T;i++) 
          if ( dis[npoint]+v[npoint][i]<dis[i] ){
          
              dis[i]=dis[npoint]+v[npoint][i]; // 更新路径 
              
              if ( !vis[i] ) ex.push_back(i); // 增加新的可扩展点 
              
          }                
    
    }  
    
    printf("%d",dis[te]);  
   
  return 0;
  
}

蒟蒻在成长~


2017.1.29



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值