这是一道很明显的最短路题,数据范围也对复杂度高如floyd的算法也极其友好qaq(难得啊5555/关于spfa死去的回忆在攻击我)对刚掌握最短路算法的同学们是一个可以试试手的简单题呢,但是对于最短路(单源最短路且仅含正权边的题)还是一定一定一定优先掌握并选择dijkstra!!!!
(但是请允许我在这里水一个floyd吧hhh)
Code:
/*思路:明显的最短路问题,不切换开关的路权值为0,其余为1
由于数据较小,跑floyd这样复杂度高的算法也是可以的(当然还是最好dijkstra,关于spfa在只有正权边的图建议忘了qaq)*/
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n, a, b;
int m[105][105];//存图
int main(){
cin >> n >> a >> b;
//memset(m, 0x7ffffff, sizeof(m));//将图中权值置为INF
//5555555这里是唯一一个有价值的知识点,这么多年第一次认真查了memset的原理,一般来说int类型只赋值为0或-1,所以乖乖用循环赋值叭
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
m[i][j] = 0x7ffffff;
}
}
for (int i = 1; i <= n; i++)
{
int k;
cin >> k;
for (int j = 1; j <= k; j++)
{
int next;
cin >> next;
if (j == 1)
m[i][next] = 0;
else
m[i][next] = 1;//注意不是无向图啊啊啊啊啊
}
}
for (int k = 1; k <= n; k++)//快乐的floyd开始咯~~~只要记得中转的路口k要写在最外层的循环就没问题啦
{
for (int i = 1; i <= n; i++)
{
if (i == k) continue;
for (int j = 1; j <= n; j++)
{
if (i == j || k == j) continue;//如果是同一个路口直接continue就行
if (m[i][j] > m[i][k] + m[k][j])//如果经过k的路更短就更新
{
m[i][j] = m[i][k] + m[k][j];
}
}
}
}
if (m[a][b] == 0x7ffffff)
{
cout << "-1";
return 0;
}
cout << m[a][b];
return 0;
}
最后有一点点感想qaq
最近打了好多次memset全部都WA了,但是我竟然没有一次想着去好好查一下memset的原理和使用方法,直到今天又一次30分WA了才终于发现了一直以来自己对memset用法的误解...(大概就是在对整形数组赋值的时候一般只在赋值为0和-1时能符合我们的要求,大多数情况我们需要数组整体赋值为INF时是不能直接用memset的)
其实还挺不能接受自己这样的错误的qaq,以后敲代码一定一定一定要把算法里每个细节还有各个调用的函数弄清楚才行!也希望大家引以为戒^_^