省选专练SHOI2012回家的路

SPFA水题

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+100;
const int INF=1e9+7;
inline void read(int &x){
	x=0;
	char ch=getchar();
	int f=1;
	while(ch<'0'||ch>'9'){
		if(ch=='-'){
			f=-1;
		}
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
struct Front_star{
	int u,v,w,nxt;
}e[N*2];
int cnt=1;
int first[N]={};
void addedge(int u,int v,int w){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].nxt=first[u];
	first[u]=cnt; 
} 
void add(int u,int v,int w){
//	cout<<u<<" "<<v<<" "<<w<<'\n';
	addedge(u,v,w);
	addedge(v,u,w);
}
struct edge{
	int x,y,id;
}E[N*4];
int n,m;
bool cmp1(edge A,edge B){
	return (A.x<B.x)||(A.x==B.x&&A.y<B.y);
}
bool cmp2(edge A,edge B){
	return (A.y<B.y)||(A.y==B.y&&A.x<B.x);
}
int S,T;
int dis[N]={};
queue<int> Q;
int inqueue[N]={};
void SPFA(){
	for(int i=0;i<N;i++){
		dis[i]=INF;
	}
//	memset(dis,0x3f,sizeof(dis));
	dis[S]=0;
	Q.push(S);
	while(!Q.empty()){
		int x=Q.front();
		Q.pop();
		inqueue[x]=0;
		for(int i=first[x];i;i=e[i].nxt){
			int v=e[i].v;
			if(dis[v]>dis[x]+e[i].w){
				dis[v]=dis[x]+e[i].w;
//				cout<<v<<" "<<x<<" "<<e[i].w<<" "<<dis[v]<<'\n';
				if(!inqueue[v]){
					Q.push(v);
					inqueue[v]=1;
				}
			}
		}
	}
}
int main(){
	freopen("P3831.in","r",stdin);
	read(n);
	read(m);
	S=m+1;
	T=m+2;
	for(int i=1;i<=m+2;i++){
		read(E[i].x);
		read(E[i].y);
		E[i].id=i;
	}
	sort(E+1,E+1+m+2,cmp1);
	for(int i=1;i<=m+1;i++){
		if(E[i].x==E[i+1].x){
			add(E[i].id,E[i+1].id,(E[i+1].y-E[i].y)*2);
		}
	}
	sort(E+1,E+1+m+2,cmp2);
	for(int i=1;i<=m+1;i++){
		if(E[i].y==E[i+1].y){
			add(E[i].id+m+2,E[i+1].id+m+2,(E[i+1].x-E[i].x)*2);
		}
	}
	for(int i=1;i<=m;i++){
		add(i,i+m+2,1);
	}
	add(m+1,m*2+3,0);
	add(m+2,m*2+4,0);
	SPFA();
	if(dis[T]==INF)puts("-1");
	else cout<<dis[T];
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/80979792