这个题目需要最短路不用多说了吧,但是关键在于,这个玩意需要选择一个点,可以是任意一个点,从这个点将现金全部兑换成旅游金,注意,是全部啊,也就是我们需要枚举在哪个点把现金全部兑换成旅游币,然后从中取一个最小的
然后我们就可以画出来这样一个图
也就是相当于,变成了从起点到p,然后从终点到p两个最短路的值相加,然后由于它有一个修改操作,我们就需要一个堆来维护,而且这个堆还需要可以修改,所以就是multiset
因为它有erease和insert
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
using namespace std;
#define x first
#define y second
#define endl '\n'
#define int long long
#define PII pair<int, int>
#define INF 0x3f3f3f3f3f3f3f3f
const int N = 1e5 + 10;
vector<PII> v1[N], v2[N];
int dist1[N], dist2[N];
bool st[N];
int rate[N];
// /*
void dij(vector<PII> v[], int dist[], int s) // 求1号点到n号点的最短路距离
{
memset(st, 0, sizeof st);
memset(dist, 0x3f, sizeof dist1);
dist[s] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, s});
while (heap.size())
{
auto t = heap.top();
heap.pop();
int ver = t.second, distance = t.first;
if (st[ver]) continue;
st[ver] = true;
for(auto i : v[ver])
{
if(dist[i.x] > dist[ver] + i.y)
{
dist[i.x] = dist[ver] + i.y;
heap.push({dist[i.x], i.x});
}
}
}
}
// */
int n, m, q;
int a, b,c, d;
signed main()
{
cin >> n >> m >> q;
for (int i = 1; i <= m; i ++ )
{
scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
v1[a].push_back({b, c});
v2[b].push_back({a, d});
}
for(int i=1; i<=n; i++) scanf("%lld", &rate[i]);
dij(v1, dist1, 1);
dij(v2, dist2, n);
multiset<int> s;
for (int i = 1; i <= n; i ++ )
if (dist1[i] != INF && dist2[i] != INF)
{
s.insert(dist1[i] + (dist2[i] + rate[i] - 1) / rate[i]);
}
while(q--)
{
scanf("%lld%lld", &a, &b);
if (dist1[a] != INF && dist2[a] != INF)
{
s.erase(s.find(dist1[a] + (dist2[a] + rate[a] - 1) / rate[a]));
rate[a] = b;
s.insert(dist1[a] + (dist2[a] + rate[a] - 1) / rate[a]);
}
printf("%lld\n", *s.begin());
}
return 0;
}
这个题目就更简单啦,DFS + 哈希,不会的话,就直接字符串骗分,爆搜!
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10, M = 110;
#define int unsigned long long
int n, m;
int pp = 131;
int p[N], h[N];
int with[N];
int g[M], ans[M];
bool st[M];
int get(int l, int r)
{
return h[r] - h[l-1] * p[r - l + 1];
}
bool dfs(int num, int s)
{
if(s == n) return true;
for(int i=1; i <= m; i++)
{
if(!st[i] && g[i] == get(s, s + with[i] - 1))
{
st[i] = 1;
ans[num] = i;
if(dfs(num + 1, s + with[i] - 1)) return true;
st[i] = 0;
}
}
return 0;
}
signed main()
{
p[0] = 1;
scanf("%d", &n);
// cout << n << endl;
int x;
for(int i = 1; i<=n; i++)
{
scanf("%d", &x);
// cout << x << ' ';
p[i] = p[i-1] * pp;
h[i] = h[i-1] * pp + x + 1;
}
// cout << endl;
scanf("%d", &m);
for(int i=1; i<=m; i++)
{
scanf("%d", &with[i]);
for(int j = 1; j<=with[i]; j++)
{
scanf("%d", &x);
g[i] = g[i] * pp + x + 1;
}
}
dfs(1, 1);
for(int i=1; i<=m; i++)
{
cout << ans[i];
if(i != m) cout << ' ';
}
}