持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路。
D. Ela and the Wiring Wizard
题目
中文大意
给我们n个点m条边每条边都有一个价值w对于边我们可以将边删除变成u,和v相邻的边或者v,与u相邻的边每次这个操作都会花费这条边的价值。这个操作可以无限次。问经历过多次操作后从点1到点n所花费的最小价值是多少\
解法
样例一
对于样例一我们可以发现只需要将这条边移动到再将移动到&1-8&即可如下图
所以我们的最小花费是
样例三
对于样例三我们是通过把这条边移动6次最终变成这条边我们所花费的价值最小为
通过样例一三我们不难猜测出最小花费就是将某一条边变成这条边
但是的连接有两种可能一种是先连接再连接然后连接另一种是将边变成关于点x的自环然后连接 最后连接
Code
const int N = 510;
const int INF = 1e18;
int g[N][N],dist[N][N];
void solve()
{
int n,m; cin >> n >> m;
rep(i,n) rep(j,n) dist[i][j] = g[i][j] = INF;
rep(i,n) dist[i][i] = dist[i][i] = 0;
rep(i,m) {
int u,v,w; cin >> u >> v >> w;
g[u][v] = g[v][u] = min(g[u][v],w);
dist[u][v] = dist[v][u] = 1;
}
rep(k,n) rep(i,n) rep(j,n) dist[i][j] = min(dist[i][j],dist[i][k] + dist[k][j]);
int res = 1e18;
rep(u,n) rep(v,n) {
if(u == v || g[u][v] == INF) continue;
res = min(res,g[u][v] * (dist[1][u] + dist[v][n] + 1));
rep(i,n)
res = min(res,g[u][v]*(dist[i][1] + dist[i][n] + 1 + dist[i][u] + 1));
}
cout << res << endl;
}