为什么优化是错的(优化部分见代码)
查看原帖
为什么优化是错的(优化部分见代码)
198212
西江月_醉楼主2021/11/17 14:42

//优化前

#include<bits/stdc++.h>
using namespace std;
#define maxn 500001
#define ll long long
#define inf 99999999999
ll T,n,m,k,tot,ans;
ll a[maxn],fir[maxn],dis[maxn],hav[maxn];
struct node{
	ll dis,num;
};
bool cmp(node x,node y){return x.dis>y.dis;}
struct Heap{
	ll siz;
	node a[maxn];
	void push(node now){
		a[++siz]=now;
		push_heap(a+1,a+siz+1,cmp);
	}
	void pop(){
		pop_heap(a+1,a+siz+1,cmp);
		siz--;
	}
	node top(){
		return a[1];
	}
	bool empty(){
		return siz==0;
	}
}q;
struct edge{
	ll to,nxt,dis;
}e[2*maxn];
void add(ll a,ll b,ll d){
	e[++tot].to=b;
	e[tot].nxt=fir[a];
	fir[a]=tot;
	e[tot].dis=d;
}
void dij(ll s){
	while(!q.empty()) q.pop();
	for(ll i=1;i<=n;i++) dis[i]=inf;//优化前每次赋初值
	dis[s]=0;
	q.push((node){0,s});
	while(!q.empty()){
		node tmp=q.top();
		q.pop();
		ll x=tmp.num,d=tmp.dis;
		if(d>ans) break;
		for(ll i=fir[x];i;i=e[i].nxt){
			ll y=e[i].to;
			if(dis[y]>dis[x]+e[i].dis){
				dis[y]=dis[x]+e[i].dis;
				if(y!=s&&hav[y]) ans=min(ans,dis[y]);
				q.push((node){dis[y],y});
			}
		}
	}
	return;
}
int main(){
	scanf("%lld",&T);
	while(T--){
	    scanf("%lld%lld%lld",&n,&m,&k);
	    memset(fir,0,sizeof(fir));
		memset(hav,0,sizeof(hav));
	    tot=0;
		for(ll i=1;i<=m;i++){
			ll a,b,d;
			scanf("%lld%lld%lld",&a,&b,&d);
			add(a,b,d);
		}
		for(ll i=1;i<=k;i++) scanf("%lld",&a[i]),hav[a[i]]=1;
		ans=inf;
		for(ll i=1;i<=k;i++) dij(a[i]);
		printf("%lld\n",ans);
	}
	return 0;
}

//优化后

#include<bits/stdc++.h>
using namespace std;
#define maxn 500001
#define ll long long
#define inf 99999999999
ll T,n,m,k,tot,ans;
ll a[maxn],fir[maxn],dis[maxn],hav[maxn];
struct node{
	ll dis,num;
};
bool cmp(node x,node y){return x.dis>y.dis;}
struct Heap{
	ll siz;
	node a[maxn];
	void push(node now){
		a[++siz]=now;
		push_heap(a+1,a+siz+1,cmp);
	}
	void pop(){
		pop_heap(a+1,a+siz+1,cmp);
		siz--;
	}
	node top(){
		return a[1];
	}
	bool empty(){
		return siz==0;
	}
}q;
struct edge{
	ll to,nxt,dis;
}e[2*maxn];
void add(ll a,ll b,ll d){
	e[++tot].to=b;
	e[tot].nxt=fir[a];
	fir[a]=tot;
	e[tot].dis=d;
}
void dij(ll s){
	ll ren=dis[s]; //优化部分
	while(!q.empty()) q.pop();
	dis[s]=0;
	q.push((node){0,s});
	while(!q.empty()){
		node tmp=q.top();
		q.pop();
		ll x=tmp.num,d=tmp.dis;
		if(d>ans) break;
		for(ll i=fir[x];i;i=e[i].nxt){
			ll y=e[i].to;
			if(dis[y]>dis[x]+e[i].dis){
				dis[y]=dis[x]+e[i].dis;
				if(y!=s&&hav[y]) ans=min(ans,dis[y]);
				q.push((node){dis[y],y});
			}
		}
	}
	dis[s]=ren;//优化部分
	return;
}
int main(){
	scanf("%lld",&T);
	while(T--){
	    scanf("%lld%lld%lld",&n,&m,&k);
	    memset(fir,0,sizeof(fir));
		memset(hav,0,sizeof(hav));
		for(ll i=1;i<=n;i++) dis[i]=inf;
	    tot=0;
		for(ll i=1;i<=m;i++){
			ll a,b,d;
			scanf("%lld%lld%lld",&a,&b,&d);
			add(a,b,d);
		}
		for(ll i=1;i<=k;i++) scanf("%lld",&a[i]),hav[a[i]]=1;
		ans=inf;
		for(ll i=1;i<=k;i++) dij(a[i]);
		printf("%lld\n",ans);
	}
	return 0;
}
2021/11/17 14:42
加载中...