2 条题解

  • 1
    @ 2025-12-7 15:27:52
    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N=5e5+10;
    #define PII pair<int,int>
    #define fi first
    #define se second
    vector<PII>G[N];
    int d[N],v[N],st,ed,pre[N],n;
    void dij()
    {
    	for(int i=1;i<=n;i++)d[i]=1e18;
    	priority_queue<PII,vector<PII>,greater<PII>>q;
    	d[st]=0;q.push({0,st});
    	while(!q.empty())
    	{
    		int x=q.top().se;q.pop();
    		if(v[x])continue;v[x]=1;
    		for(auto i:G[x])
    		{
    			int y=i.fi,w=i.se;
    			if(d[y]>d[x]+w)
    			{
    				d[y]=d[x]+w;
    				pre[y]=x;
    				if(!v[y])q.push({d[y],y});
    			}
    		}
    	}
    }
    signed main()
    {
    	int m;cin>>n>>m>>st>>ed;st++,ed++;
    	for(int i=1;i<=m;i++)
    	{
    		int x,y,w;cin>>x>>y>>w;x++,y++;
    		G[x].push_back({y,w});
    	}
    	dij();
    	if(d[ed]!=1e18)
    	{
    		stack<PII>stk;
    		int z=ed;
    		while(z!=st)
    		{
    			stk.push({pre[z],z});
    			z=pre[z];
    		}
    		cout<<d[ed]<<' '<<stk.size()<<'\n';
    		while(!stk.empty())cout<<stk.top().fi-1<<' '<<stk.top().se-1<<'\n',stk.pop();
    		return 0;
    	}
    	cout<<-1<<'\n';
    	return 0;
    }
    
    • 0
      @ 2026-2-10 14:57:24

      我来水题解了!!!

      kevin的代码,我写了点注释,dij详见P1088

      #include<bits/stdc++.h>
      using namespace std;
      #define int long long
      const int N=5e5+10;
      #define PII pair<int,int>
      #define fi first
      #define se second
      vector<PII>G[N];
      int d[N],v[N],st,ed,pre[N],n;
      void dij()//标准的 Dijkstra 
      {
      	for(int i=1;i<=n;i++)d[i]=1e18;
      	priority_queue<PII,vector<PII>,greater<PII>>q;
      	d[st]=0;q.push({0,st});
      	while(!q.empty())
      	{
      		int x=q.top().se;q.pop();
      		if(v[x])continue;v[x]=1;
      		for(auto i:G[x])
      		{
      			int y=i.fi,w=i.se;
      			if(d[y]>d[x]+w)
      			{
      				d[y]=d[x]+w;
      				pre[y]=x;//当y找到了到它的最短路,记录它的前缀(父亲节点) 
      				if(!v[y])q.push({d[y],y});
      			}
      		}
      	}
      }
      signed main()
      {
      	int m;cin>>n>>m>>st>>ed;st++,ed++;//题目要求0~n-1,不习惯 
      	for(int i=1;i<=m;i++)
      	{
      		int x,y,w;cin>>x>>y>>w;x++,y++;
      		G[x].push_back({y,w});
      	}
      	dij();
      	if(d[ed]!=1e18)//如果有路(简单图不保证联通) 
      	{
      		stack<PII>stk;//记录答案 
      		int z=ed;
      		while(z!=st)//从结束点开始不停访问前缀 
      		{
      			stk.push({pre[z],z});
      			z=pre[z];
      		}
      		cout<<d[ed]<<' '<<stk.size()<<'\n';
      		while(!stk.empty())cout<<stk.top().fi-1<<' '<<stk.top().se-1<<'\n',stk.pop();
      		return 0;
      	}
      	cout<<-1<<'\n';
      	return 0;//完结撒花 
      }
      
      • @ 2026-2-10 14:58:21

        感谢Kevin的代码 (虽然没经过ta同意)

    • 1

    信息

    ID
    8161
    时间
    500ms
    内存
    1024MiB
    难度
    7
    标签
    递交数
    53
    已通过
    12
    上传者