「NOIP2012」 文化之旅 - 最短路

2024-01-02 07:58
文章标签 短路 之旅 文化 noip2012

本文主要是介绍「NOIP2012」 文化之旅 - 最短路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次(即如果他学习了某种文化,则他就不能到达其他有这种文化的国家)。不同的国家可能有相同的文化。不同文化的国家对其他文化的看法不同,有些文化会排斥外来文化(即如果他学习了某种文化,则他不能到达排斥这种文化的其他国家)。

现给定各个国家间的地理关系,各个国家的文化,每种文化对其他文化的看法,以及这位使者游历的起点和终点(在起点和终点也会学习当地的文化),国家间的道路距离,试求从起点到终点最少需走多少路。

输入输出格式

输入格式

第一行为五个整数 N , K , M , S , T N,K,M,S,T N,K,M,S,T,每两个整数之间用一个空格隔开,依次代表国家个数(国家编号为1到 N N N),文化种数(文化编号为 1 1 1 K K K),道路的条数,以及起点和终点的编号(保证 S ≠ T S \neq T S̸=T);

第二行为 N N N个整数,每两个整数之间用一个空格隔开,其中第 i i i个数 C i C_i Ci,表示国家 i i i的文化为 C i C_i Ci

接下来的 K K K行,每行 K K K个整数,每两个整数之间用一个空格隔开,记第 i i i行的第 j j j个数为 a i j a_{ij} aij a i j = 1 a_{ij} =1 aij=1 表示文化 i 排斥外来文化 j j j i = j i = j i=j时表示排斥相同文化的外来人), a i j = 0 a_{ij}=0 aij=0表示不排斥(注意 i i i排斥 j j j 并不保证 j j j一定也排斥 i i i)。

接下来的 M M M行,每行三个整数 u , v , d , u,v,d, uvd每两个整数之间用一个空格隔开,表示国家 u u u与国家 v v v有一条距离为 d d d的可双向通行的道路(保证 u u u不等于 v v v,两个国家之间可能有多条道路)。

输出格式

输出只有一行,一个整数,表示使者从起点国家到达终点国家最少需要走的距离数(如果无解则输出-1)。

输入输出样例

输入样例#1

2 2 1 1 2
1 2
0 1
1 0
1 2 10

输出样例#1

-1

输入样例#2

2 2 1 1 2
1 2
0 1
0 0
1 2 10

输出样例#2

10

样例解释

输入输出样例#1:

由于到国家 2 必须要经过国家 1,而国家 2 的文明却排斥国家 1 的文明,所以不可能到达国家 2。

输入输出样例#2:

路线为1->2。

数据规模与约定

对于 100%的数据,有$2≤N≤100,1≤K≤100,1≤M≤N^2 $

1 ≤ k i ≤ K , 1 ≤ u , v ≤ N , 1 ≤ d ≤ 1000 , S ≠ T , 1 ≤ S , T ≤ N 1≤k_i≤K ,1≤u,v≤N,1≤d≤1000,S≠T,1≤S,T≤N 1kiK,1u,vN,1d1000,S̸=T,1S,TN

分析

这道题让我们求 S S S T T T的最短路,自然地想到用最短路径算法。可这里的限制条件太多,怎么下手?别急,慢慢来。

首先,由于数据范围较小,可以用Floyd,也可用Spfa。对于学到的文化,这里用一个map从int到bool的映射存储。其实相当于可以作为数据类型的数组。每学到一个新文化,就将 m a p [ i ] = 1 map[i]=1 map[i]=1,其中 i i i是学到的文化,并将其作为参数,放在队列里。

其次,对于特殊情况的处理以及重边的处理。即 c [ S ] = c [ T ] c[S]=c[T] c[S]=c[T]时,要进行特判,直接输出 − 1 -1 1

虽然还有一种更简单的求最短路的方法,但这样可以对付加强数据。

另外,此题还可用DFS做,这里就不贴代码了。

代码

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <utility>
#include <map>
#define ll long long
#define mp make_pair
#define inf 0x7fffffff/2
using namespace std;
int n,k,m,s,t;
int c[1005],a[105][105];
int g[105][105];
int now[105];
int d[105],vis[105];
queue<pair<int,map<int,bool> > > q;
pair<int,map<int,bool> > temp;
void spfa(int v0) {for (int i = 1;i <= n;i++) d[i]=inf;map<int,bool> now;now[c[v0]]=1;q.push(mp(v0,now));d[v0]=0;vis[v0]=1;while (!q.empty()) {temp=q.front();int w=temp.first;q.pop();vis[w]=0;for (int i = 1;i <= n;i++) {if (w!=i&&g[w][i]==inf) continue;int flag=0;now=temp.second;for (int j = 1;j <= k;j++) {if (a[c[i]][j]==1&&now[j]) {flag=1;break;}}if (flag) continue;if (d[i]>d[w]+g[w][i]) {d[i]=d[w]+g[w][i];if (!vis[i]) {now[c[i]]=1;vis[i]=1;q.push(mp(i,now));}}}}
}
int main() {scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);for (int i = 1;i <= n;i++) scanf("%d",c+i);for (int i = 1;i <= k;i++)for (int j = 1;j <= k;j++)scanf("%d",&a[i][j]);for (int i = 1;i <= n;i++)for (int j = 1;j <= n;j++)g[i][j]=inf;for (int i = 1;i <= m;i++) {int a,b,cc;scanf("%d%d%d",&a,&b,&cc);g[a][b]=g[b][a]=min(g[a][b],cc);}if (c[s]==c[t]) {printf("-1");return 0;}spfa(s);if (d[t]==inf) printf("-1");else printf("%d",d[t]);return 0;
}

这篇关于「NOIP2012」 文化之旅 - 最短路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/561821

相关文章

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问

poj 3159 (spfa差分约束最短路) poj 1201

poj 3159: 题意: 每次给出b比a多不多于c个糖果,求n最多比1多多少个糖果。 解析: 差分约束。 这个博客讲差分约束讲的比较好: http://www.cnblogs.com/void/archive/2011/08/26/2153928.html 套个spfa。 代码: #include <iostream>#include <cstdio>#i

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

poj 3255 次短路(第k短路) A* + spfa 或 dijkstra

题意: 给一张无向图,求从1到n的次短路。 解析: A* + spfa 或者 dijkstra。 详解见上一题:http://blog.csdn.net/u013508213/article/details/46400189 本题,spfa中,stack超时,queue的效率最高,priority_queue次之。 代码: #include <iostream>#i

poj 2449 第k短路 A* + spfa

poj 2449: 题意: 给一张有向图,求第k短路。 解析: A* + spfa。 一下转自:http://blog.csdn.net/mbxc816/article/details/7197228 “描述一下怎样用启发式搜索来解决K短路。 首先我们知道A*的基础公式:f(x)=g(x)+h(x);对h(x)进行设计,根据定义h(x)为当前的x点到目标点t所需要的实际距

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

poj 3259 最短路负环

John的农场里N块地,M条路连接两块地,W个虫洞,虫洞是一条单向路,会在你离开之前把你传送到目的地,就是当你过去的时候时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。简化下,就是看图中有没有负权环。有的话就是可以,没有的话就是不可以了。 import java.io.BufferedReader;import java.io.InputStream;

POJ1724最短路

n个点,拥有总的价值money m条边(u,v,len ,cost),长度len,代价cost 求不超过money的代价条件下最短路。 public class Main {public static void main(String[] args) {new Task().solve();}}class Task {InputReader in = new InputReader