求助
查看原帖
求助
160839
Prean楼主2020/7/11 12:03

思路:三遍SPFA,前两遍对两个GPS分别SPFA,记录前驱边和前驱节点,并根据这个将第二场图的边权修改。

60tps。。。样例没过。。。求助QAQ

假如算法错误,请指出错误之处qwq

#include<cstdio>
#include<deque>
const int M=1e4+5,INF=0x7fffffff;
int n,m,cnt[3],h[3][M];
int d[3][M],preE[3][M],preN[3][M];
struct Edge{
	int to,val,nx;
}e[3][M*5];
inline void Add(int x,int y,int val,int id){
	e[id][++cnt[id]]=(Edge){y,val,h[id][x]};h[id][x]=cnt[id];
}
inline void SPFA(Edge*e,int*h,int*d,int*preE,int*preN){
	static bool vis[M];
	std::deque<int>q;
	int u,v,E;
	for(u=1;u<=n;++u)d[u]=INF;
	d[1]=0;q.push_back(1);
	while(!q.empty()){
		vis[u=q.front()]=0;q.pop_front();
		for(E=h[u];E;E=e[E].nx){
			v=e[E].to;
			if(d[u]+e[E].val<d[v]){
				d[v]=d[u]+e[E].val;
				preE[v]=E;preN[v]=u;
				if(!vis[v]){
					vis[v]=1;
					if(d[v]<d[q.front()])q.push_front(v);
					else q.push_back(v);
				}
			}
		}
	}
}
inline void Add(int id){
	int t=n;
	while(preN[id][t]){
		--e[2][preE[id][t]].val;
		t=preN[id][t];
	}
}
signed main(){
	int i;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;++i){
		int x,y,z;
		scanf("%d%d",&x,&y);
		Add(x,y,2,2);
		scanf("%d",&z);
		Add(x,y,z,0);
		scanf("%d",&z);
		Add(x,y,z,1);
	}
	SPFA(e[0],h[0],d[0],preE[0],preN[0]);Add(0);
//	for(i=1;i<=n;++i)printf("%d ",d[0][i]);printf("\n");
	SPFA(e[1],h[1],d[1],preE[1],preN[1]);Add(1);
//	for(i=1;i<=n;++i)printf("%d ",d[1][i]);printf("\n");
	SPFA(e[2],h[2],d[2],preE[2],preN[2]);
	printf("%d",d[2][n]);
}
2020/7/11 12:03
加载中...