1 条题解

  • 0
    @ 2025-10-10 19:47:17

    C++ :

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 2e5;
    int n,m;
    
    //链式前向星存储 
    struct Edge{
    	int u,v,next;
    	int len;
    }edge[MAXN*2];
    
    //存储每个点的第一(最后一条)条边的信息 
    int pre[20010];
    int k = 1;//数组下标 
    
    int d[20010];//存储走到每个点的最短路径
    bool vis[20010];//存储每个点在spfa中是否访问过 
    int q[40010]; //队列 
    
    //追加边 
    void add(int from,int to,int l){
    	edge[k].u = from;
    	edge[k].v = to;
    	edge[k].len = l;//权值 
    	edge[k].next = pre[from];	
    	pre[from] = k;
    	k++;
    }
    
    //spfa求权边有负数的最短路
    void spfa(){
    	//初始化d数组
    	memset(d,0x3f,sizeof(d));
    	
    	int head = 1;
    	int tail = 1;
    	q[1] = 1;//从第1个点出发
    	d[1] = 0;//走到第1个点的最短路是0
    	vis[1] = true;//出发点标记一下
    	
    	int u,v,l;
    	while(head <= tail){
    		u = q[head];//准备让u点出队
    		vis[u] = false;//标记u点走过
    		head++;
    		
    		//找u点所有的邻接点
    		for(int i = pre[u];i != 0;i = edge[i].next){
    			v = edge[i].v;//可以去的点 
    			l = edge[i].len;//权值 
    			//如果走到u的最短路+uv的路径<走到v点记录的路径
    			if(d[u] + l < d[v]){
    				d[v] = d[u] + l;
    				//如果v不在队列中,存入队列
    				if(vis[v] == false){
    					tail++;
    					q[tail] = v;
    					vis[v] = true;//标记v点走过 
    				} 
    			} 
    		} 
    		 
    	} 
    	 
    } 
    
    int main(){
    	cin>>n>>m;
    	int x,y,l;
    	for(int i = 1;i <= m;i++){
    		cin>>x>>y>>l;
    		add(x,y,l);//有向图 
    	}
    	
    	spfa();
    	
    	//输出1号点到其他点的最短路径
    	for(int i = 2;i <= n;i++){
    		cout<<d[i]<<endl;
    	} 
    	 
    } 
    
    • 1

    信息

    ID
    969
    时间
    1000ms
    内存
    512MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者