• L2-001 紧急救援 (25分)


    在这里插入图片描述
    与一般最短路题目相比,多了节点的权重以及输出路径。
    在简单的djs基础上,多了到达每个节点的最大救援数以及更新路径:倒序更新,使用pre函数,如在pre[s(终点)]可能的值中找到最大救援的路径,这样就不仅满足>关系更新,=时也要更新。

    inline void djs()
    {
    	for(re int i=1;i<=n;i++)dis[i]=2147483647;
    	dis[s]=0;
    	priority_queue<node>Q;//初始化
    	
    	node a ={s,0};
    	Q.push(a);//第一个node
    	
    	while(!Q.empty())
    	{
    		node fr=Q.top();Q.pop();
    		int u=fr.u,d=fr.d;
    		//取出并记录
    		if(d!=dis[u])continue;//避免处理无用数据,也就是dis[u]已经更新,之前未更新数据直接出栈,比如有一组数据 2 5,但是后面又入栈一组数据2 3,则2 5是无用数据
    		for(re int j=0;j<g[u].size();j++)
    		{
    			int tm=g[u][j].to;
    			if(dis[u]+g[u][j].cost<dis[tm])
    			{			 
                	dis[tm]=dis[u]+g[u][j].cost;
    				Q.push((node){tm,dis[tm]});
    			}
    		}
    	}
    }
    
    #include<bits/stdc++.h>
    #define intn long long
    #define ls(k) (k)<<1
    #define inf 2147483647
    #define re register
    #define rs(k) (k)<<1|1
    #define _0for(i, a) for(int i = 0; i < (a); ++i)
    #define _1for(i, a) for(int i = 1; i <=(a); ++i)
    #define lowbit(x) ((x)&(-x))
    #define debug(x) 
    (void)(cerr << "L" << __LINE__
    			<< " : " << #x << " = " 
    			<< (x) << endl )
    
    using namespace std;
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct edge
    {
    	int to,cost;
    };
    struct node
    {
    	int u,d;
    	bool operator <(const node&rhs)const
    	{
    		return d>rhs.d;
    	}
    };
    int n,dis[20000],s,m,d;
    vector<edge>g[50000];
    int road[20000];
    int jy[200000];
    int pre[200000];
    int gejy[200000];
    void djs()
    {
    	for(re int i=0;i<=n;i++)dis[i]=inf;
    	dis[s]=0;
    	priority_queue<node>Q;
    	node a={s,0};
    	Q.push(a);
    	while(!Q.empty())
    	{
    		node fr=Q.top();
    		Q.pop();
    		int u=fr.u,d=fr.d;
    		if(road[u]==0)road[u]=1;
    		if(d!=dis[u])continue;
    		for(re int j=0;j<g[u].size();j++)
    		{
    			int tm=g[u][j].to;
    			if(dis[u]+g[u][j].cost<dis[tm])
    			{
    				dis[tm]=dis[u]+g[u][j].cost;
    				Q.push((node){tm,dis[tm]});
    				road[tm]=road[u];
    				pre[tm]=u;
    				gejy[tm]=gejy[u]+jy[tm];
    			}
    			else if(dis[u]+g[u][j].cost==dis[tm])
    			{
    				road[tm]+=road[u];
    				if(gejy[tm]<gejy[u]+jy[tm])//找到最大救援数的节点。
    				{
    					pre[tm]=u;
    				}
    				gejy[tm]=max(gejy[tm],gejy[u]+jy[tm]);
    			}
    		}
    	}
    }
    void outpath()
    {
    	stack<int> st;
    	st.push(d);
    	for(int i=pre[d];i!=-1;i=pre[i])
    	{
    		st.push(i);
    	}
    	int x=st.top();
    	printf("%d",x);
    	st.pop();
    	while(!st.empty())
    	{
    		int x=st.top();
    		printf(" %d",x);
    		st.pop();
    	}
    }
    main(void)
    {
    	cin>>n>>m>>s>>d;
    	fill(pre,pre+10000,-1);
    	for(int i=0;i<n;i++)
    	{
    		cin>>jy[i];
    		gejy[i]=jy[i];
    	}
    	for(int i=0;i<m;i++)
    	{
    		int a,b,c;
    		cin>>a>>b>>c;
    		g[a].push_back(edge{b,c});
    		g[b].push_back(edge{a,c});
    	}
    	djs();
    	printf("%d %d
    ",road[d],gejy[d]);
    	outpath();
    }
    
    
  • 相关阅读:
    UIKit, AppKit, 以及其他API在多线程当中的使用注意事项
    BOZJ-2590 优惠券
    P3620 [APIO/CTSC 2007] 数据备份
    矩阵乘法与快速幂
    CodeForces
    AtCoder
    CodeForces
    考试成绩和学号的(结构体)排序
    CodeForces
    Atcoder Beginner Contest 092 —— C题
  • 原文地址:https://www.cnblogs.com/wangqianyv/p/14050052.html
Copyright © 2020-2023  润新知