题解:P1078 [NOIP2012 普及组] 文化之旅
Charles_with_wkc · · 题解
声明:
本题,看了题解区发现只有
因为本题不一定存在正确的解法换句话说:就是错题,所以有 hack 也很正常吧。
思路:
本题使用的是 dijkstra 算法求最短路,但是这道题不同的一点是,这里面出现了文化歧视,文化不重复学习等。我们可以加入标记来让本题可以愉快地使用 dijkstra 算法。
代码:
#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 了。
如果是我代码的问题,希望大佬指出。
玄学合集:
玄学1 Floyd 92pts
玄学2 dijkstra+A* 没过样例,但是 AC 了
玄学3 正搜对 4 个,逆搜对 3 个
玄学4 第 10 个点,本地 RE,洛谷神速
玄学5 没有判断条件 AC
玄学6 dfs 对 4 个点,删掉回溯 AC
玄学7 样例没过 AC
玄学8 倒搜没有该判断 AC 了
玄学9 不合理的 AC,加了 vis 直接卡到 0ms
玄学10 第 10 个点 1008ms
以上是作者翻阅讨论区得到的玄学合集。