rt,悬赏关注
#include <bits/stdc++.h>
#define INF 0x7fffffff
#define double long double
using namespace std;
const int MAXN = 60;
const int T_0 = 1000;
const int T_k = 1e-10;
const int d = 0.99995;
inline int read()
{
int x = 0; char ch = getchar();
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch xor 48), ch = getchar();
return x;
}
inline void write (int x)
{
if (x > 9) write(x / 10);
putchar (x % 10 + 48);
}
int n, m, k, V[MAXN]; bool flag[MAXN]; int have[MAXN], no, _no[MAXN];
struct Edge { int to, val, next; }e[MAXN << 1]; int head[MAXN], cnt;
inline void add (int u, int v, int w) { e[++ cnt] = (Edge){v, w, head[u]}, head[u] = cnt; }
inline void input()
{
n = read(), m = read(), k = read();
for (register int i = 1; i <= n; ++ i) V[i] = read() + 1;
for (register int u = 1, w; u <= n; ++ u)
w = read(), add(u, V[u], w), add(V[u], u, w);
for (register int i = 1, x; i <= m; ++ i)
x = read() + 1, flag[x] = true, have[i] = x;
}
int ans, dis[MAXN]; bool vis[MAXN];
struct Node
{
int id, dis;
friend bool operator < (Node x, Node y)
{ return x.dis > y.dis; }
};
inline int calc()
{
priority_queue <Node> q;
for (register int i = 1; i <= n; ++ i) vis[i] = false, dis[i] = INF;
for (register int i = 1; i <= m; ++ i)
dis[have[i]] = 0, q.push((Node){have[i], dis[have[i]]});
for (register int i = 1; i <= min(k, no); ++ i)
dis[_no[i]] = 0, q.push((Node){_no[i], dis[_no[i]]});
while (!q.empty())
{
int u = q.top().id; q.pop();
if (vis[u]) continue;
vis[u] = true;
for (register int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
if (dis[u] + e[i].val < dis[v])
dis[v] = dis[u] + e[i].val, q.push((Node){v, dis[v]});
}
}
int res = 0;
for (register int i = 1; i <= no; ++ i)
res = max(res, dis[_no[i]]);
ans = min(ans, res);
return res;
}
inline void init()
{
for (register int i = 1; i <= n; ++ i)
if (!flag[i]) _no[++ no] = i;
ans = calc();
if (no == k) { write(ans), putchar('\n'); exit(0); }
}
inline double Rand() { return (double)(rand()) / RAND_MAX; }
inline void SA()
{
double T = T_0;
int now = ans;
while (T > T_k)
{
int x = rand() % k + 1, y = rand() % (no - k) + k + 1;
swap (_no[x], _no[y]);
int nxt = calc();
double delta = nxt - now;
if (exp(-delta / T) > Rand()) now = nxt;
else swap(_no[x], _no[y]);
T *= d;
}
}
inline void output() { write(ans), putchar('\n'); }
int main()
{
srand (time(0));
input();
init();
while ((double)(clock()) / CLOCKS_PER_SEC < 0.795) SA();
output();
return 0;
}