Wannafly挑战赛2 B.Travel 最短路+思维
Posted kaka0010
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wannafly挑战赛2 B.Travel 最短路+思维相关的知识,希望对你有一定的参考价值。
原题链接:https://ac.nowcoder.com/acm/contest/17/B
题意
先给你一个n个点组成的环,现在在上面加m条边,m小于20,最后询问任意两点之间的最短路。
分析
先从m入手,m非常小,因此肯定是从m条边连接的点出发,去跑2m遍最短路,预处理出这2m个点到图上所有点的最短路。
对于xy之间的最短路一定只有三种情况:
- 不经过后加的边,那可以O1直接算出值
- x到u,u到v,v到y
- x到v,v到u,u到y
因此暴力枚举所有加边,对于这三种情况取一个最小值就可以了。
这题有点卡内存
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ul;
typedef pair<int, int> PII;
const ll inf = 1e18;
const int N = 55500;
const int M = 1e6 + 10;
const ll mod = 1e9 + 7;
const double eps = 1e-8;
#define lowbit(i) (i & -i)
#define Debug(x) cout << (x) << endl
#define fi first
#define se second
#define mem memset
#define endl '\\n'
namespace StandardIO {
template<typename T>
inline void read(T &x) {
x = 0; T f = 1;
char c = getchar();
for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
x *= f;
}
template<typename T>
inline void write(T x) {
if (x < 0) putchar('-'), x *= -1;
if (x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
}
namespace Comb {
ll f[N];
ll ksm(ll a, ll b) {
ll res = 1, base = a;
while (b) {
if (b & 1) res = res * base % mod;
base = base * base % mod;
b >>= 1;
}
return res;
}
void init() {
f[0] = 1;
for (ll i = 1; i < N; i++) f[i] = f[i - 1] * i % mod;
}
ll C(ll a, ll b) {
if (a < 0 || b < 0 || b > a) return 0;
return f[a] * ksm(f[a - b], mod - 2) % mod * ksm(f[b], mod - 2) % mod;
}
}
namespace Seg {
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
ll sum[N<<2], tag[N<<2];
void push_up(int u) {
sum[u] = sum[u<<1] + sum[u<<1|1];
}
void push_down(int u, int l, int r) {
if (tag[u]) {
tag[u<<1] += tag[u];
tag[u<<1|1] += tag[u];
sum[u<<1] += 1ll*(mid-l+1)*tag[u];
sum[u<<1|1] += 1ll*(r-mid)*tag[u];
tag[u] = 0;
}
}
void modify(int u, int ql, int qr, int l, int r, int val) {
if (ql <= l && qr >= r) {
sum[u] += 1ll*(r-l+1)*val;
tag[u] += val;
return;
}
push_down(u, l, r);
if (ql <= mid) modify(ls, ql, qr, l, mid, val);
if (qr > mid) modify(rs, ql, qr, mid+1, r, val);
push_up(u);
}
}
namespace ST {
int mi[N][21], ma[N][21], lg[N], a[N], gcd[N][21];
int cmp1(int x, int y) {
return a[x] < a[y] ? x : y;
}
int cmp2(int x, int y) {
return a[x] > a[y] ? x : y;
}
void init(int n) {
for (int i = 1; i <= n; i++) {
cin >> a[i];
gcd[i][0] = a[i];
ma[i][0] = mi[i][0] = i, lg[i] = log2(i);
}
for (int i = 1; i <= 20; i++) {
for (int j = 1; j + (1 << i) - 1 <= n; j++) {
mi[j][i] = cmp1(mi[j][i - 1], mi[j + (1 << (i - 1))][i - 1]);
ma[j][i] = cmp2(ma[j][i - 1], ma[j + (1 << (i - 1))][i - 1]);
gcd[j][i] = __gcd(gcd[j][i - 1], gcd[j + (1 << (i - 1))][i - 1]);
}
}
}
int qry_mi(int l, int r) {
int k = lg[r - l + 1];
return a[cmp1(mi[l][k], mi[r - (1 << k) + 1][k])];
}
int qry_ma(int l, int r) {
int k = lg[r - l + 1];
return a[cmp2(ma[l][k], ma[r - (1 << k) + 1][k])];
}
int qry_pmi(int l, int r) {
int k = lg[r - l + 1];
return cmp1(mi[l][k], mi[r - (1 << k) + 1][k]);
}
int qry_pma(int l, int r) {
int k = lg[r - l + 1];
return cmp2(ma[l][k], ma[r - (1 << k) + 1][k]);
}
int qry_gcd(int l, int r) {
int k = lg[r - l + 1];
return __gcd(gcd[l][k], gcd[r - (1 << k) + 1][k]);
}
}
struct Edge {
int to, next, w;
}e[N<<1];
int cnt, h[N];
void add(int u, int v, int w) {
e[cnt].to = v;
e[cnt].w = w;
e[cnt].next = h[u];
h[u] = cnt++;
}
struct Bridge {
int u, v, w;
};
vector<Bridge> E;
ll dis[41][N], pre[N];
int vis[N], d[N];
struct node {
ll d;
int now;
bool operator < (const node &rhs) const {
return d > rhs.d;
}
};
map<int, int> id;
void dij(int st) {
priority_queue<node> que;
int ID = id[st];
memset(vis, 0, sizeof vis);
memset(dis[ID], 0x3f, sizeof dis[ID]);
dis[ID][st] = 0;
que.push({0, st});
while (que.size()) {
int now = que.top().now;
que.pop();
if (vis[now]) continue;
vis[now] = 1;
for (int i = h[now]; ~i; i = e[i].next) {
int v = e[i].to;
if (dis[ID][v] > dis[ID][now] + e[i].w) {
dis[ID][v] = dis[ID][now] + e[i].w;
if (!vis[v]) {
que.push({dis[ID][v], v});
}
}
}
}
}
inline void solve() {
int n, m; cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i++) {
cin >> d[i]; pre[i] = pre[i - 1] + d[i];
add(i, i % n + 1, d[i]);
add(i % n + 1, i, d[i]);
}
for (int i = 1; i <= m; i++) {
int u, v, w; cin >> u >> v >> w;
add(u, v, w), add(v, u, w);
E.push_back({u, v, w});
}
int tot = 0;
for (auto it : E) {
if (!id[it.u]) id[it.u] = ++tot;
if (!id[it.v]) id[it.v] = ++tot;
dij(it.u);
dij(it.v);
}
int q; cin >> q; while (q--) {
int x, y; cin >> x >> y;
if (x > y) swap(x, y);
ll tmp = min(pre[y-1] - pre[x-1], pre[n-1] - pre[y-1] + d[n] + pre[x-1]);
for (auto it : E) {
tmp = min(dis[id[it.u]][x] + dis[id[it.v]][y] + it.w, tmp);
tmp = min(dis[id[it.u]][y] + dis[id[it.v]][x] + it.w, tmp);
}
cout << tmp << endl;
}
}
signed main()<以上是关于Wannafly挑战赛2 B.Travel 最短路+思维的主要内容,如果未能解决你的问题,请参考以下文章