牛客多校-Journey-(建图distra+卡常优化)

J

题意:
就是给你n个十字路口,每个路口有四个方向,按逆时针给你路口的标号,如果是0标号代表没有路口。然后你每次在路口进行右转是不花费的,然后前进,左转,倒头,都是花费1。先在你在A路口对着B路口的路上,让你走到在C路口对着D路口的路上。问你最少的花费。你面对的方向是不用的,A对B和B对A是不一样的。

思考:
其实这题,给你的路口,也没给你指定的方向,只是逆序的给你。如果按路口跑最短路会发现这个图不好弄。所以要按边跑,也就是把边看成点,把这些边看成不同的点,进行hash。怎么想到呢,因为问的就是从这个路走到那个路的花费,所以把路看成点比较好做。建图的时候就是枚举一个路口的四个路口,然后找出两个路口,对他们建图,如果是右转那么不花费。
然后值得注意的呢是,用map<PII,int>哈希会超时,那么换成unordered_map<PII,int,cmp>。这个cmp重载用法不一样也会有的超时有的不超。当然最保险的是可以不建图,直接跑,跑的时候枚举到哪就行了。哈希的时候把边哈希成特别大的值再放到unordered_map<int,int>就可以了。

代码:

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
		
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 5e6+10,M = 2010;

int T,n,m,k;
int va[N][4];
int dist[N],vis[N];

struct cmp{
	int operator()(PII A)const{
		return A.fi*521417+A.se;
	}
};

int cnt;
unordered_map<PII,int,cmp> mp;

vector<PII > e[N];

void distra(int A)
{
	for(int i=1;i<=cnt;i++) dist[i] = inf;
	priority_queue<PII,vector<PII>,greater<PII> > q;
	q.push({0,A});
	dist[A] = 0;
	while(q.size())
	{
		auto t = q.top();q.pop();
		int now = t.se,dis = t.fi;
		if(vis[now]) continue;
		for(auto tt:e[now])
		{
			int spot = tt.fi,w = tt.se;
			if(dist[spot]>dist[now]+w)
			{
				dist[spot] = dist[now]+w;
				q.push({dist[spot],spot});
			}
		}
	}
}

signed main()
{
	IOS;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<4;j++)
		{
			cin>>va[i][j];
			if(!va[i][j]) continue;
			int a = i,b = va[i][j];
			if(!mp[{a,b}]) mp[{a,b}] = ++cnt;
			if(!mp[{b,a}]) mp[{b,a}] = ++cnt;
		}
		for(int j=0;j<4;j++)
		{
			if(!va[i][j]) continue;
			for(int k=0;k<4;k++)
			{
				if(!va[i][k]) continue;
				int a = va[i][j],b = i,c = va[i][k],w = 1;
				if((j+1)%4==k) w = 0;
				int x = mp[{a,b}],y = mp[{b,c}];
				e[x].pb({y,w});
			}
		}
	}
	int A,B,C,D;
	cin>>A>>B>>C>>D;
	distra(mp[{A,B}]);
	if(dist[mp[{C,D}]]==inf) cout<<-1;
	else cout<<dist[mp[{C,D}]];
	return 0;
}

总结:
多多尝试把,我感觉map不行的时候,unordered也不行,就不想写了。一点一点优化,也许最后就过了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值