• 【CF】【Dijkstra】E. Buy and Delete


    【CF】【Dijkstra】E. Buy and Delete

    题目传送门

    image

    两个任务,一个是要跑出最短路,其二是在跑出最短路的时候,将所有边权进行一次汇总,要求在所有的最短路中,这生成的最短路的边权和是最小的。

    image

    设蓝球为起点,蓝球可以通过两条相等的路到达绿球,但为了使得总路径最小,要选择有经过蓝色边的这条路径。

    为了方便比较我们可以开设一个cost数组用来记录某一个结点所转移过来的中的边中边权最小的边的边权,同时开一个pre数组去记录这个边的边号,方便后续答案的统计。

    #include <bits/stdc++.h>
    #define pii pair<ll,ll>
    #define FI first
    #define SE second
    #define ll long long
    #define de(x) cout<<" enter : "<<x<<endl;
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0' && ch<='9')
            x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int N = 3E5+100,M = 6E5+100;
    ll h[N],ne[M],e[M],w[M],mark[M],idx;
    void add(int u,int v,ll wei,int pos)
    {
    	e[idx] = v,ne[idx] = h[u],w[idx] = wei,mark[idx] = idx/2+1,h[u] = idx++;
    }
    ll n,m,pre[N],used[N],dist[N],cost[N];
    void dij(int u)
    {
    	memset(dist,0x3f,sizeof(dist));
    	priority_queue<pii,vector<pii>,greater<pii>> heap;
    	dist[u] = 0;
    	heap.push({0,u});
    	while(heap.size())
    	{
    		pii t = heap.top();
    		heap.pop();
    		ll d = t.FI, u = t.SE;
    		if(used[u]) continue;
    		used[u] = true;
    		for(int i = h[u];~i;i=ne[i])
    		{
    			int v = e[i];
    			if(dist[v]>d+w[i])
    			{
    				dist[v] = d + w[i];
    				heap.push({dist[v],v});
    				cost[v] = w[i];
    				pre[v] = mark[i]; 
    			}
    			else if(dist[v]==d+w[i])
    				if(cost[v]>w[i])
    				{
    					cost[v] = w[i];
    					pre[v] = mark[i];
    				}
    		}
    	}
    }
    int main()
    {
    	memset(h,-1,sizeof(h));
    	n = read(), m = read();
    	for(int i=1;i<=m;i++)
    	{
    		int u = read(), v = read(), wei = read();
    		add(u,v,wei,i);add(v,u,wei,i);
    	}
    	dij(read());
    	ll sum = 0;
    	for(int i=1;i<=n;i++)
    		sum += cost[i];
    	sort(pre+1,pre+1+n);
    	cout<<sum<<endl;
    	for(int i=2;i<=n;i++)
    	    cout<<pre[i]<<" ";
        return 0;
    }
    
    
  • 相关阅读:
    Redis 高级数据结构:五、哈希对象
    Redis 高级数据结构:四、列表对象
    Redis 高级数据结构:三、字符串对象
    Redis 高级数据结构:二、简介
    总结1
    Windows程序代码重构
    Windows应用程序结构
    事件、消息循环和窗口函数
    窗口的创建和显示
    Windows的数据类型
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15575168.html
Copyright © 2020-2023  润新知