题目连接
题意
给一张 n 个顶点, n-1 条边的图, 最大二百条询问从 u 到 v 的最近距离
题解
这里是广搜实现的, 起点搜到终点, dis数组保存距离
这个题数据太坑了, 这个说好了 n-1 条边, 开这么大的数组存边, 却是一直超时, 把数组开大了就过了. 但这也应该是报 re , 坑
两种存图方式对于这个题来说时间没有影响太多, vector占的内存大了一些
代码
链式前向星存图
#include <bits/stdc++.h>
using namespace std;
#define rg register
#define sc scanf
#define pf printf
typedef long long ll;
const int MAXN = 4e4+10;
const int MAXM = 9e4+10; // 坑, 链式前向星超时是因为范围开小了, 也不报 re , 太坑了!!
struct EDGE {
int v, w, to;
}e[MAXM];
int head[MAXM], cnt = 0, dis[MAXN]; bool vis[MAXN];
inline void add ( int u, int v, int w ) {
e[cnt].v = v, e[cnt].w = w, e[cnt].to = head[u]; head[u] = cnt++;
}
int bfs ( int st, int ed ) {
queue<int> q;
while ( !q.empty() ) q.pop();
memset ( vis, false, sizeof(vis) );
memset ( dis, 0, sizeof ( dis ) );
q.push ( st );
vis[st] = true;
while ( !q.empty ( ) ) {
int u = q.front( );
q.pop( );
if ( u == ed ) break;
for ( int k = head[u]; k != -1; k = e[k].to ) {
int v = e[k].v;
if ( vis[v] ) continue;
q.push ( v );
vis[v] = true;
dis[v] = dis[u] + e[k].w;
}
}
return dis[ed];
}
int main ( ) {
int n, m, T,
u, v, w;
sc ( "%d", &T );
while ( T-- ) {
sc ( "%d%d", &n, &m );
cnt = 0,
memset( head, -1, sizeof(head) );
for ( int i = 0; i < n - 1; ++i ) {
sc ( "%d%d%d", &u, &v, &w );
add( u, v, w );
add( v, u, w );
}
for ( int i = 0; i < m; ++i ) {
sc ( "%d %d", &u, &v );
pf ( "%d\n", bfs( u, v ) );
}
if ( T!=0 ) puts( "" );
}
return 0;
}
vector模拟邻接表存图
#include <bits/stdc++.h>
using namespace std;
#define rg register
#define sc scanf
#define pf printf
typedef long long ll;
const int MAXN = 4e4+10;
struct EDGE {
int v, w;
};
vector<EDGE> e[MAXN];
int dis[MAXN];
bool vis[MAXN];
int bfs ( int st, int ed ) {
queue<int> q;
while ( !q.empty() ) q.pop();
memset ( vis, false, sizeof(vis) );
memset ( dis, 0, sizeof ( dis ) );
q.push ( st );
vis[st] = true;
while ( !q.empty ( ) ) {
int u = q.front ();
q.pop ( );
if ( u == ed )break;
for ( int i = 0; i < e[u].size ( ); ++i ) {
int v = e[u][i].v;
if ( vis[v] ) continue;
q.push ( v );
vis[v] = true;
dis[v] = dis[u] + e[u][i].w;
}
}
return dis[ed];
}
int main ( ) {
int n, m, T,
u, v, w;
sc ( "%d", &T );
while ( T-- ) {
sc ( "%d%d", &n, &m );
for ( int i = 0; i <= n; ++i )
e[i].clear ( );
for ( int i = 0; i < n - 1; ++i ) {
sc ( "%d%d%d", &u, &v, &w );
e[u].push_back( (EDGE){ v, w } );
e[v].push_back( (EDGE){ u, w } );
}
for ( int i = 0; i < m; ++i ) {
sc ( "%d %d", &u, &v );
pf ( "%d\n", bfs( u, v ) );
}
if ( T!=0 ) puts( "" );
}
return 0;
}