专栏文章

题解:P1078 [NOIP2012 普及组] 文化之旅

P1078题解参与者 5已保存评论 4

文章操作

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

当前评论
4 条
当前快照
1 份
快照标识符
@miqep5il
此快照首次捕获于
2025/12/04 03:35
3 个月前
此快照最后确认于
2025/12/04 03:35
3 个月前
查看原文

声明:

本题,看了题解区发现只有 11 篇 dijkstra 的算法,于是有了这篇题解。
因为本题不一定存在正确的解法换句话说:就是错题,所以有 hack 也很正常吧。

思路:

本题使用的是 dijkstra 算法求最短路,但是这道题不同的一点是,这里面出现了文化歧视,文化不重复学习等。我们可以加入标记来让本题可以愉快地使用 dijkstra 算法。

代码:

CPP
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int N=105;
struct node{
	int v,w;
};
struct nodee{
	int u,d;
	int used[N];//哪种语言使用过了 
	bool operator<(const nodee &A)const{
		return A.d<d;
	}
};
vector<node>edge[N];
bool vis[N],qs[N][N];
int dis[N],c[N];
int n,f,t,w,m,u,st,en,k,v;
void dijkstra(int st){
	priority_queue<nodee>q;
	nodee ccf;
	ccf.u=st;
	ccf.d=0;
	for(int i=1;i<=k;i++) ccf.used[i]=0;
	q.push(ccf);//封装存储 
	fill(dis,dis+1+n,1e9);//最大值初始化 
	dis[st]=0;
	while(!q.empty()){
		u=q.top().u;
		nodee us=q.top();
		q.pop();
		if(vis[u]||us.used[c[u]]) continue;
		vis[u]=1;
		us.used[c[u]]=1;
		for(int i=1;i<=k;i++)
			if(qs[c[u]][i]) us.used[i]=1;//歧视 
		for(node e:edge[u]){
			v=e.v;
			w=e.w;
			if(us.used[c[v]]) continue; 
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				if(!vis[v]){
					ccf.d=dis[v];
					ccf.u=v;
					for(int j=1;j<=k;j++) ccf.used[j]=us.used[j];
					q.push(ccf);
				}
			}
		}
	}
	if(dis[en]!=1e9) cout<<dis[en];
	else cout<<-1;
	return ;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>k>>m>>st>>en;
	for(int i=1;i<=n;i++) cin>>c[i];
	for(int i=1;i<=k;i++)
		for(int j=1;j<=k;j++) cin>>qs[i][j];
	while(m--){
		cin>>f>>t>>w;
		edge[f].push_back(node{t,w});
		edge[t].push_back(node{f,w});
	}
	dijkstra(st);
	return 0;
}

尾言:

本题不保证存在可以通过满足本题数据范围的任意数据做法。由于测试数据过水,可以通过此题的程序不一定完全正确(算法时间复杂度错误、或不保证正确性)。本题题目和数据仅供参考。本题不接受添加 hack 数据。
本题为错题。不建议尝试或提交本题关于此类题目的详细内容
所以,我的代码没有过样例,但是 AC 了。
如果是我代码的问题,希望大佬指出。

玄学合集:

评论

4 条评论,欢迎与作者交流。

正在加载评论...