社区讨论

警钟乱敲

P3831[SHOI2012] 回家的路参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lzkocue9
此快照首次捕获于
2024/08/08 10:44
2 年前
此快照最后确认于
2024/08/19 11:19
2 年前
查看原帖
这条题目如果你想判起点/终点/车站重合,千万不要使用map
如下,删去map不判重后不仅时间非常充裕,8,9WA直接AC了,有点神奇(
CPP
#include <bits/stdc++.h>
using namespace std;
#define N 400005
#define add(u,v,w) e[u].push_back( Edge(v,w) )
struct point{
	int x,y;
}p[N];
struct Edge{
	int v,w;
	Edge(){}
	Edge(int vv,int time):v(vv),w(time){}
};
struct node{
	int id,tim;
};
vector<Edge> e[N];
int n,m,k;
vector<int> xe[N],ye[N];
//map< int,map<int,int> > ma;
int d[N],vst[N],st,ed;
bool operator < (node a,node b)
{
	return a.tim > b.tim;
}
void dij()
{
	memset(d,0x3f,sizeof(d));
	memset(vst,0,sizeof(vst));
	priority_queue<node> q;
	d[st]=0;
	q.push({st,d[st]});
	while(!q.empty())
	{
		int u=q.top().id;
		q.pop();
		if(vst[u]) continue;
		vst[u]=1;
		for(auto j:e[u])
		{
			int v=j.v;
			int w=j.w;
			if(d[u]+w < d[v])
			{
				d[v]=d[u]+w;
				q.push({v,d[v]});
			}
		}
	}
	return;
}
void init()
{
	cin>>n>>m;
	int a,b;
	int firm=m;
	for(int i=1;i<=firm+2;i++)
	{
		cin>>a>>b;
		if(i==firm+1)
		{
		/*	if(ma[a][b])
			{
				st=ma[a][b];
				continue;
			}*/
			st=i;
			m++;
		}
		else if(i==firm+2)
		{
		/*	if(ma[a][b])
			{
				ed=ma[a][b];
				continue;
			}*/
			ed=i;
			m++;
		}
		xe[a].push_back(i);
		ye[b].push_back(i);
		p[i].x=a,p[i].y=b;
	//	ma[a][b]=i;
	}
	for(int i=1;i<=firm;i++)
	{
		add(i,i+m,1);
		add(i+m,i,1);//change-edge
	}
	for(int i=1;i<=m;i++)
	{
		for(auto j : xe[p[i].x]) //x same
		{
			if(i==j) continue;
			add(i,j, abs(p[j].y-p[i].y)*2 );
		//	add(j,i, abs(p[j].y-p[i].y)*2 );
		} 
		for(auto j : ye[p[i].y]) //y same
		{
			if(i==j) continue;
			add(i+m,j+m, abs(p[j].x-p[i].x)*2 );
		//	add(j+m,i+m, abs(p[j].x-p[i].x)*2 );
		}    
	}
	return;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	init();
	
//	for(auto i:ye[1])
//		cout<<i<<" ";
/*	for(int i=1;i<=m*2;i++)
	{
		cout<<i<<" : ";
		for(auto j:e[i])
			cout<<j.v<<" ";
		cout<<'\n';
	}*/
///	for(int i=1;i<=2*m;i++)
//		cout<<d[i]<<" ";
	int ans=0x3f3f3f3f;
	dij();
	ans=min(ans,min(d[ed],d[ed+m]));
	st+=m;
	dij();
	ans=min(ans,min(d[ed],d[ed+m]));
	if(ans==0x3f3f3f3f)
		cout<<-1;
	else
		cout<<ans;	
	return 0;
}
所以具体的原因,或许是因为map下标有限制之类(?

回复

1 条回复,欢迎继续交流。

正在加载回复...