zoukankan      html  css  js  c++  java
  • P1342 请柬

    题面

    思路:挺裸的最短路。

    首先从(1)号站点到其他的站点的最小花费很容易想到单源最短路。

    那么从其他站点返回(1)号站点的最小花费呢?从每个终点站点跑一遍Dijkstra吗?

    不不不,首先从时间复杂度上就不对,时间复杂度基本上是(O(n^2logn))的,而我们的(n)(1e6),明显不可以。

    我们考虑反向建边,从(1)号点跑两边Dijkstra。

    为什么要反向建边,仔细想想,不难,我们从起点出发顺着边走可以到达其他点,那么我们把边反过来,再顺着走,不就相当于从其他点到起点吗。感性理解一下??

    啊实在不行照着下面的图自己手玩一遍??这样更形象更具体。

    画图来形象的理解一下qwq:

    这是未反向建边的原图:

    (1)号点可以跑Dijkstra即可求出到其他点的最小花费。

    反向建边后的图:

    这个时候我们从(1)号点跑Dijkstra,所求出的到其他点的最小花费,不正是其他点返回(1)号点的最小花费嘛。

    感觉反向建边是最短路和一些其他问题差不多都是图论问题??中挺常用的思路的。

    啊对还要注意开long long,不然会爆int。分析一下?

    一共(1e6)条边,每条边的极限权值为(1e9)来回一趟极限值差不多为(2e15),而int的极限值为(2147483647)差不多是(2e9),已经爆了int了。

    其实我们应该养成理性分析的习惯,不要等OJ返回WA的时候才恍然大悟:哦,这道题要开long long!这句话才不是在说我呢qaq!!应该除了我没人犯这种错误吧orz。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    template<typename temp>void read(temp &x){
    	x = 0;temp f = 1;char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') and (f = -1);
    	for(x = ch^48; isdigit(ch = getchar()); x = (x<<1)+(x<<3)+(ch^48));
    	x *= f;
    }
    template <typename temp, typename ...Args>void read(temp& a, Args& ...args){read(a), read(args...);}
    
    const int maxn = 1e6+10;
    
    int n, m;
    long long ans, dis_to[maxn], dis_from[maxn], vis_to[maxn], vis_from[maxn];
    
    vector<pair<int,int> > v_to[maxn], v_from[maxn];
    
    void qwq(){return;}
    
    void Dijkstra_to(){
    	memset(dis_to, 0x3f, sizeof(dis_to));
    	priority_queue<pair<long long,int>, vector<pair<long long,int> >, greater<pair<long long,int> > >q;
    	q.push(make_pair(0,1));
    	dis_to[1] = 0;
    	while (q.size()){
    		int now = q.top().second, len = q.top().first;
    		q.pop();
    		if(vis_to[now]) continue;
    		vis_to[now] = 1;
    		for(int i = 0; i < v_to[now].size(); i ++){
    			int to = v_to[now][i].first, length = v_to[now][i].second;
    			if(dis_to[to] > len + length){
    				dis_to[to] = len + length;
    				q.push(make_pair(dis_to[to], to));
    			}
    		}
    	}
    	return qwq();
    }
    
    void Dijkstra_from(){
    	memset(dis_from, 0x3f, sizeof(dis_from));
    	priority_queue<pair<long long,int>, vector<pair<long long,int> >, greater<pair<long long,int> > >q;
    	q.push(make_pair(0,1));
    	dis_from[1] = 0;
    	while (q.size()){
    		int now = q.top().second, len = q.top().first;
    		q.pop();
    		if(vis_from[now]) continue;
    		vis_from[now] = 1;
    		for(int i = 0; i < v_from[now].size(); i ++){
    			int to = v_from[now][i].first, length = v_from[now][i].second;
    			if(dis_from[to] > len + length){
    				dis_from[to] = len + length;
    				q.push(make_pair(dis_from[to], to));
    			}
    		}
    	}
    	return qwq();
    }
    
    signed main(){
    	read(n, m);
    	for(int i = 1, x, y, z; i <= m; i ++){
    		read(x, y, z);
    		v_to[x].push_back(make_pair(y,z));
    		v_from[y].push_back(make_pair(x,z));
    	}
    	Dijkstra_to();
    	Dijkstra_from();
    	for(int i = 1; i <= n; i ++) ans += dis_to[i]+dis_from[i];
    	printf("%lld", ans);
    	return 0;
    }
    
  • 相关阅读:
    PKU 学生的反馈 20091
    PKU 学生的反馈 2009 –2
    中国队有进步
    刚发现博客园又遇到了问题
    今日计划
    Delphi中使用多线程
    在老ASP中使用对象的对象生存期问题
    ASP与Javascript
    ASP & VBScript的错误处理
    对前一段时间学习网络和多线程编程的总结
  • 原文地址:https://www.cnblogs.com/Vanyun/p/13420345.html
Copyright © 2011-2022 走看看