[NOIP] [最短路] [SPFA] NOIP2012Junior 文化之旅 (culture)
来源:互联网 发布:郑州大学软件学院 一本 编辑:程序博客网 时间:2024/05/23 21:26
题目描述 Description
有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次(即如果他学习了某种文化,则他就不能到达其他有这种文化的国家)。不同的国家可能有相同的文化。不同文化的国家对其他文化的看法不同,有些文化会排斥外来文化(即如果他学习了某种文化,则他不能到达排斥这种文化的其他国家)。
现给定各个国家间的地理关系,各个国家的文化,每种文化对其他文化的看法,以及这位使者游历的起点和终点(在起点和终点也会学习当地的文化),国家间的道路距离,试求从起点到终点最少需走多少路。
输入 Input
第一行为五个整数
N,K,M,S,T ,每两个整数之间用一个空格隔开,依次代表国家个数(国家编号为1 到N ),文化种数(文化编号为1 到K ),道路的条数,以及起点和终点的编号(保证S 不等于T );
第二行为N 个整数,每两个整数之间用一个空格隔开,其中第i 个数Ci ,表示国家i的文化为Ci 。
接下来的K 行,每行K 个整数,每两个整数之间用一个空格隔开,记第i 行的第j 个数为aij ,aij=1 表示文化i 排斥外来文化j (i 等于j 时表示排斥相同文化的外来人),aij=0 表示不排斥(注意i 排斥j 并不保证j 一定也排斥i )。
接下来的M 行,每行三个整数u,v,d ,每两个整数之间用一个空格隔开,表示国家u 与国家v 有一条距离为d 的可双向通行的道路(保证u 不等于v ,两个国家之间可能有多条道路)。
输出 Output
输出只有一行,一个整数,表示使者从起点国家到达终点国家最少需要走的距离数(如果无解则输出
−1 )。
样例输入#1 Sample Input#1
2 2 1 1 2
1 2
0 1
1 0
1 2 10
样例输出#1 Sample Output#1
-1
样例输入#2 Sample Input#2
2 2 1 1 2
1 2
0 1
0 0
1 2 10
样例输出#2 Sample Output#2
10
Limits 限制
对于
20% 的数据 有2≤N≤8,K≤5
对于30% 的数据 有2≤N≤10,K≤5
对于50% 的数据 有2≤N≤20,K≤8
对于70% 的数据 有2≤N≤100,K≤10
对于100% 的数据 有2≤N≤100,1≤K≤100,1≤M≤N2,1≤Ci≤K,1≤u,v≤N,1≤d≤1000,S≠T,1≤S,T≤N。
Time Limit :1s & Memory Limit :128MB
(当年普及组考SPFA+最短路乱搞也是醉了……)
最短路没的说,SPFA先打上,关键是还得搞一个东西维护题里条件,于是就有了(瞎搞)的基础
直接看代码吧…….(数组名很人性化)
(其实好几处还能优化……不过VJ已经
#include <cstdio>#include <cstring>#include <climits>#define MAXN 110int n,m,k,s,t,x,u,v,w;int culture[MAXN];int against_num[MAXN];int against[MAXN][MAXN];int road[MAXN][MAXN],road_dis[MAXN][MAXN];int road_num[MAXN];int dis[MAXN];int q[MAXN];//手写队列,其实可以用STLbool inq[MAXN],can_arrive[MAXN],arrive[MAXN][MAXN];//can_arrive:can_arrive[i]=true表明在走的路径上可以经过i(合法路一定满足路上的文化没有与t国文化对立的)//arrive:第一维是国家,第二维是文化,表明到达i国家学习到j文化的状态bool check(int a,int b){ for (int i=1;i<=against_num[culture[b]];i++) if (arrive[a][against[culture[b]][i]]) return false; if (culture[a]==culture[b]) return false; //判断是否满足不重复学习同种文化(貌似不加也能过?) else return true;}int spfa(){ int head=0,tail=1; for (int i=1;i<=n;i++) dis[i]=INT_MAX; q[tail]=s;arrive[s][culture[s]]=true; inq[s]=true; dis[s]=0; while (head!=tail) { head=(head%n)+1; inq[q[head]]=false; for (int i=1;i<=road_num[q[head]];i++) { if(check(q[head],road[q[head]][i])) //判断要到达的国家和已到达的国家文化是否冲突和是否学习相同文化 { if (can_arrive[culture[road[q[head]][i]]]) { if (dis[q[head]]+road_dis[q[head]][i]<dis[road[q[head]][i]]) //正常SPFA { dis[road[q[head]][i]]=dis[q[head]]+road_dis[q[head]][i]; for (int j=1;j<=k;j++) //继承状态 arrive[road[q[head]][i]][j]=arrive[q[head]][j]; arrive[road[q[head]][i]][culture[road[q[head]][i]]]=true; if (!inq[road[q[head]][i]]) { inq[road[q[head]][i]]=true; tail=(tail%n)+1; q[tail]=road[q[head]][i]; } } } } } } if (dis[t]==INT_MAX) return -1; else return dis[t];}int main(){ scanf("%d %d %d %d %d",&n,&k,&m,&s,&t); for (int i=1;i<=n;i++) scanf("%d",&culture[i]); for (int i=1;i<=k;i++) for (int j=1;j<=k;j++) { scanf("%d",&x); if (x==1) { against_num[i]++; against[i][against_num[i]]=j; } } for (int i=1;i<=m;i++) { scanf("%d %d %d",&u,&v,&w); road_num[u]+=1; road[u][road_num[u]]=v; road_dis[u][road_num[u]]=w; road_num[v]+=1; road[v][road_num[v]]=u; road_dis[v][road_num[v]]=w; } memset(can_arrive,true,sizeof(can_arrive)); memset(inq,false,sizeof(inq)); memset(arrive,false,sizeof(arrive)); for (int i=1;i<=against_num[culture[t]];i++) can_arrive[against[culture[t]][i]]=false; printf("%d\n",spfa()); return 0;}
话说当年出这么难题配了个巨水的数据……
- [NOIP] [最短路] [SPFA] NOIP2012Junior 文化之旅 (culture)
- NOIP 2012 普及组 复赛 culture 文化之旅
- culture文化之旅
- 最短路-------文化之旅
- 【NOIP模板】 最短路 spfa
- 沐枫NOI 2835. 文化之旅(2012年NOIP普及组4) 最短路
- 最短路之SPFA
- SPFA算法之最短路。
- 最短路之SPFA模板
- 最短路之SPFA模板
- 最短路之SPFA算法
- 最短路之SPFA算法
- 最短路之SPFA模板
- 【原创】【NOIP】文化之旅
- HDOJ 2544 最短路 (简单的最短路之spfa)
- 图论浅析--最短路之SPFA
- 最短路算法之SPFA算法
- 最短路之 dijkstra & floyed &SPFA
- safari地址栏无法使用百度搜索
- JavaScript五子棋
- 页面跳转(pop返回多个ViewController)
- 大数据下的TopK算法
- 不可多得的Javascript(AJAX)开发工具 - Aptana
- [NOIP] [最短路] [SPFA] NOIP2012Junior 文化之旅 (culture)
- MySql MESSAGE: java.net.ConnectException: Connection refuse
- Mysql 查询数据
- Ajax结合json在web中的应用
- Mysql 创建、修改和删除表
- [转]Berkeley DB设计经验
- 放平常心
- poj 1797
- 190. Reverse Bits