40分求助!
查看原帖
40分求助!
388391
我是小何子啊楼主2021/3/9 13:08

用了最普通的方法,先跑一遍SPFA判负环,然后跑n遍Dijkstra求最短路,只有40分不知道怎么改了,求大佬们看一看!

#include<queue>
#include<cstdio>
#define oo 1e9
using namespace std;
int n,m,a,b,c,tmp,head[1000001];
long long dis[1000001],das[1000001],vis[1000001],vas[1000001],t[1000001];
struct node{
	int to,w,next;
}e[90000001];
void add(int x,int y,int z){
	e[tmp].to=y;
	e[tmp].w=z;
	e[tmp].next=head[x];
	head[x]=tmp++; 
}
bool spfa(int x){
	queue<int>q;
	dis[x]=0;
	vis[x]=1;
	q.push(x);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u];i!=-1;i=e[i].next){
			if(dis[e[i].to]>dis[u]+e[i].w){
				dis[e[i].to]=dis[u]+e[i].w;
				if(!vis[e[i].to]){
					++t[e[i].to];
					if(t[e[i].to]>=n) return false;
					vis[e[i].to]=1;
					q.push(e[i].to);
				}
			}
		}
	}
	return true;
}
void dijkstra(int x){
	priority_queue<pair<long long,int> >q;
	for(int i=1;i<=n;++i) das[i]=oo,vas[i]=0;
	das[x]=0;
	q.push(make_pair(0,x));
	while(!q.empty()){
		int k=q.top().second;
		q.pop();
		for(int i=head[k];i!=-1;i=e[i].next){
			if(das[e[i].to]>das[k]+e[i].w){
				das[e[i].to]=das[k]+e[i].w;
				if(!vas[e[i].to]){
					vas[e[i].to]=1;
					q.push(make_pair(-das[e[i].to],e[i].to));
				}
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n;++i) head[i]=-1;
	for(int i=1;i<=m;++i){
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
	}
	for(int i=1;i<=n;++i) dis[i]=oo,add(0,i,0);
	if(!spfa(0)){
		printf("-1");
		return 0;
	}
	for(int i=1;i<=n;++i){
		for(int j=head[i];j!=-1;j=e[j].next){
			e[j].w+=dis[i]-dis[e[j].to];
		}
	}
	for(int i=1;i<=n;++i){
		dijkstra(i);
		long long ans=0;
		for(int j=1;j<=n;++j){
			if(das[j]==oo) ans+=1e9*j;
			else ans+=(das[j]-dis[i]+dis[j])*j;
		}
		printf("%lld\n",ans);
	}
	return 0;
}
2021/3/9 13:08
加载中...