有关dij 和 spfa 的时间差距
查看原帖
有关dij 和 spfa 的时间差距
234224
青鸟_Blue_Bird楼主2020/9/11 21:01

RT, 按照时间复杂度来讲,堆优化的 dijdij 是肯定要远快于 spfaspfa 的,但是在这一题好像???我的 spfaspfa 跑得比 dijdij 快多了。请问大佬们是因为STL STL 队列常数过大还是我写徦了

https://www.luogu.com.cn/record/38281270 (dij版本)

#include <bits/stdc++.h>
using namespace std;
#define N 110
#define ll long long
const ll inf = (ll)1e12 + 10; 

template <class T>
inline void read(T& a){
	T x = 0, s = 1;
	char c = getchar();
	while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
	a = x * s;
	return ; 
}

struct node{
	int v, next;
	int w;
	
	node(int v = 0, int w = 0, int next = 0){
		this -> v = v;
		this -> w = w;
		this -> next = next;
		return ; 
	}
} t[1000010];
int f[N]; 

int bian = 0;
inline void addedge(int u, int v, int w){
	t[++bian] = node(v, w, f[u]), f[u] = bian;
	t[++bian] = node(u, w, f[v]), f[v] = bian;
	return ;
}

ll dp[N]; 
ll d[N];  
int n, m, k, e; 

vector <int> G[N]; 
ll cost[N][N];
bool vis[N], ban[N];  

struct point{
	int u, dis;
	
	bool operator < (const point& a) const{
		return dis > a.dis; 
	}
};

void dij(int s){
	priority_queue <point> q; 
	for(int i = 1; i <= n; i++) vis[i] = 0, d[i] = inf;
	d[s] = 0;
	q.push((point){s, 0});
	
	while(!q.empty()){
		int now = q.top().u; q.pop();
		if(!vis[now]){
			vis[now] = 1;
			for(int i = f[now]; i; i = t[i].next){
				int v = t[i].v;
				if(ban[v]) continue;
				if(d[v] > d[now] + t[i].w){
					d[v] = d[now] + t[i].w;
					if(!vis[v]) q.push((point){v, d[v]}); 
				}
			}
		}
	}
	return ; 
}

int main(){ 
	read(m), read(n), read(k), read(e);
	for(int i = 1; i <= e; i++){
		int x, y, w; 
		read(x), read(y), read(w);
		addedge(x, y, w); 
	}
	int sum;
	read(sum);
	for(int i = 1; i <= sum; i++){
		int num, a, b;
		read(num), read(a), read(b);
		for(int j = a; j <= b; j++)
			G[j].push_back(num); 		
	}
	for(int i = 1; i <= m; i++){
		for(int j = 1; j <= m; j++){
			memset(ban, 0, sizeof(ban));
			for(int k = i; k <= j; k++)
				for(int l = 0; l < G[k].size(); l++)
					ban[G[k][l]] = 1; 
			dij(1);
			cost[i][j] = d[n]; 		
		}
	}
	for(int i = 1; i <= m; i++) dp[i] = inf; 
	for(int i = 1; i <= m; i++){
		dp[i] = cost[1][i] * i; 
		for(int j = i-1; j >= 0; j--){ 
			dp[i] = min(dp[j] + cost[j+1][i] * (i-j) + k, dp[i]);
		}
	}
	cout << dp[m] << endl;
	return 0; 
}

https://www.luogu.com.cn/record/38281084 (spfa版本)

#include <bits/stdc++.h>
using namespace std;
#define N 110
#define ll long long
const ll inf = (ll)1e12 + 10; 

template <class T>
inline void read(T& a){
	T x = 0, s = 1;
	char c = getchar();
	while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
	a = x * s;
	return ; 
}

struct node{
	int v, next;
	int w;
	
	node(int v = 0, int w = 0, int next = 0){
		this -> v = v;
		this -> w = w;
		this -> next = next;
		return ; 
	}
} t[1000010];
int f[N]; 

int bian = 0;
inline void addedge(int u, int v, int w){
	t[++bian] = node(v, w, f[u]), f[u] = bian;
	t[++bian] = node(u, w, f[v]), f[v] = bian;
	return ;
}

ll dp[N]; 
ll d[N];  
int n, m, k, e; 

vector <int> G[N]; 
ll cost[N][N];
bool vis[N], ban[N];  


void spfa(int s){
	queue <int> q; 
	for(int i = 1; i <= n; i++) d[i] = inf, vis[i] = 0;
	d[s] = 0;
	vis[s] = 1;
	q.push(s);
	
	while(!q.empty()){
		int now = q.front(); q.pop();
		vis[now] = 0;
		for(int i = f[now]; i; i = t[i].next){
			int v = t[i].v;
			if(ban[v]) continue; 
			if(d[v] > d[now] + t[i].w) {
				d[v] = d[now] + t[i].w;
				if(!vis[v]) 
					q.push(v), vis[v] = 1; 
			}
		}
	}
	return ; 
}

int main(){ 
	read(m), read(n), read(k), read(e);
	for(int i = 1; i <= e; i++){
		int x, y, w; 
		read(x), read(y), read(w);
		addedge(x, y, w); 
	}
	int sum;
	read(sum);
	for(int i = 1; i <= sum; i++){
		int num, a, b;
		read(num), read(a), read(b);
		for(int j = a; j <= b; j++)
			G[j].push_back(num); 		
	}
	for(int i = 1; i <= m; i++){
		for(int j = 1; j <= m; j++){
			memset(ban, 0, sizeof(ban));
			for(int k = i; k <= j; k++)
				for(int l = 0; l < G[k].size(); l++)
					ban[G[k][l]] = 1; 
			spfa(1);
			cost[i][j] = d[n]; 		
		}
	}
	for(int i = 1; i <= m; i++) dp[i] = inf; 
	for(int i = 1; i <= m; i++){
		dp[i] = cost[1][i] * i; 
		for(int j = i-1; j >= 0; j--){ 
			dp[i] = min(dp[j] + cost[j+1][i] * (i-j) + k, dp[i]);
		}
	}
	cout << dp[m] << endl;
	return 0; 
}
2020/9/11 21:01
加载中...