zoukankan      html  css  js  c++  java
  • 对于有向图多个点到一个点的求法

    对于一个有向图,我们要求多个点到一个点的距离怎么办?反向存图

    拿这道题为例子吧qwq (Link)

    我们求完1到所有的点的距离后,最朴素的做法就是再对每一个点跑一次最短路。但是这样做肯定会超时的,因为我们只用求多个点到一个点的距离,但是我们求了这些点对其他点的距离,这根Floyd有什么区别吗(Floyd好像真的能过啊 草(v.)),这时,我们把所有边反过来,再跑一次1的最短路不就行了吗?代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int n , m , ans;
    int dis[1000010] , vis[1000010];
    vector<pair<int , int> > e[1000010];
    vector<pair<int , int> > fe[1000010];
    void work(int st){
    	queue<int> q; 
    	memset(dis, 127 , sizeof(dis));
    	memset(vis , 0 , sizeof(vis));
    	dis[st] = 0;
    	vis[st] = 1;
    	q.push(st);
    	while(!q.empty()){
    		int x = q.front();
    		q.pop();
    		vis[x] = 0;
    		for(int i = 0; i < e[x].size(); i++){
    			int y = e[x][i].first , w = e[x][i].second;
    			if(dis[y] > dis[x] + w){
    				dis[y] = dis[x] + w;
    				if(!vis[y]){
    					vis[y] = 1;
    					q.push(y);
    				}
    			}
    		}
    	}
    }
    int main(){
    	cin >> n >> m;
    	for(int i = 1; i <= m; i++){
    		int x , y , z;
    		cin >> x >> y >> z;
    		e[x].push_back(make_pair(y , z));
    		fe[y].push_back(make_pair(x , z));
    	}
    	work(1);
    	for(int i = 2; i <= n; i++) ans += dis[i];
    	for(int i = 1; i <= n; i++) e[i].clear();
    	for(int i = 1; i <= n; i++)
    		for(int j = 0; j < fe[i].size(); j++) e[i].push_back(make_pair(fe[i][j].first , fe[i][j].second));
    	work(1);
    	for(int i = 2; i <= n; i++) ans += dis[i];
    	cout << ans;
    	return 0;
    }
    

    亿个建议:没事就别打SPFA了,除非有负环之类的,我这里打主要是为了复习一下SPFA。

    这道题有三倍经验!!!

    (Link1)

    (Link2)

  • 相关阅读:
    java-String类
    多线程的细节
    java-多线程的练习----妖,等待唤醒,代码重构,lock到condition
    javascript函数的声明和调用
    表单
    java-多线程的入门_进阶总结
    uboot命令
    u-boot移植 III
    u-boot移植 II
    汇编词典
  • 原文地址:https://www.cnblogs.com/bzzs/p/13179074.html
Copyright © 2011-2022 走看看