这道题卡两天了终于解决了,竟然是数组开小了出现runtime error,原来还以为是超时了,不停的优化算法,写注释,修改代码。。。。
练这么长时间竟然连超时和runtime error不分…………orz
runtime error原因
1、数组开得太小了,导致访问到了不该访问的内存区域
2、发生除零错误
3、大数组定义在函数内,导致程序栈区耗尽
4、指针用错了,导致访问到不该访问的内存区域
5、还有可能是程序抛出了未接收的异常
这道题先反向bfs确定最短路径再正向bfs找到最短路中权值和最小的那条路……
代码:
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <queue>
#include <climits>
#include <algorithm>
using namespace std;
const int maxn = 2000000;
int n, m; // n个点,m条边
/* 邻接表 */
int u[maxn]; // 起点
int v[maxn]; // 终点
int w[maxn]; // 权值
/* 每个点到终点的最短距离 */
int d[maxn];
/* bfs一般都得用一个vis数组防止重复遍历呀 */
int vis[maxn];
/* 表示每个起点的邻接表idx */
vector<int> G[maxn];
/* 最后的答案 */
int ans[maxn];
/* 建立邻接表 */
void add_edge(int p0, int p1, int col, int cur) {
if (p0 == p1) return;
for(int i = 0; i < G[p0].size(); i++) {
int idx = G[p0][i];
int vp = v[idx];
if (vp == p1) {
if (col >= w[idx]);
else {
w[idx] = col;
}
}
}
for(int i = 0; i < G[p1].size(); i++) {
int idx = G[p1][i];
int vp = v[idx];
if (vp == p0) {
if (col >= w[idx]) return;
else {
w[idx] = col;
return;
}
}
}
u[cur*2] = p0;
v[cur*2] = p1;
w[cur*2] = col;
G[p0].push_back(cur*2);
u[cur*2+1] = p1;
v[cur*2+1] = p0;
w[cur*2+1] = col;
G[p1].push_back(cur*2+1);
}
/* 反向BFS,目的是找到i点距离终点的最短路的大小,并保存到d[i]中 */
void rev_bfs() {
memset(vis, 0, sizeof(vis));
queue<int> qu;
qu.push(n);
d[n] = 0;
vis[n] = 1;
while(!qu.empty()) {
int up = qu.front(); qu.pop();
for(int i = 0; i < G[up].size(); i++) {
int idx = G[up][i];
int vp = v[idx];
if (!vis[vp]) {
vis[vp] = 1;
d[vp] = d[up] + 1;
qu.push(vp);
}
}
}
}
void bfs() {
memset(vis, 0, sizeof(vis));
vis[1] = 1;
queue<int> qu;
qu.push(1);
while (!qu.empty()) {
int up = qu.front();
qu.pop();
if (d[up] == 0) continue;
int mincol = INT_MAX;
for (int i = 0; i < G[up].size(); i++) {
int idx = G[up][i];
int vp = v[idx];
if (d[up] == d[vp] + 1) {
mincol = min(mincol, w[idx]);
}
}
int t = d[1] - d[up];
if (t < 0) goto en;
if (ans[t] == -1) {
ans[t] = mincol;
} else ans[t] = min(mincol, ans[t]);
en:
for (int i = 0; i < G[up].size(); i++) {
int idx = G[up][i];
int vp = v[idx];
if (!vis[vp] && d[vp] + 1 == d[up] && w[idx] == mincol) {
qu.push(vp);
vis[vp] = 1;
}
}
}
}
/* 初始化 */
void init() {
for(int i = 1; i <= n; i++) {
G[i].clear();
}
memset(d, -1, sizeof(d));
memset(ans, -1, sizeof(ans));
}
/* 打印结果 */
void print_ans() {
printf("%d\n", d[1]);
printf("%d", ans[0]);
for(int i = 1; i < d[1]; i++) {
printf(" %d", ans[i]);
}
printf("\n");
}
int main(){
freopen("input.txt", "r", stdin);
while(~scanf("%d%d", &n, &m)) {
init();
int p0, p1, col;
for(int i = 0; i < m; i++) {
scanf("%d%d%d", &p0, &p1, &col);
add_edge(p0, p1, col, i);
}
rev_bfs();
bfs();
print_ans();
}
return 0;
}
总结:当出现runtime error的时候不妨把数组开大一点……