Dytechlab Cup 2022D. Ela and the Wiring Wizard(最短路)

56 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路。
D. Ela and the Wiring Wizard
题目

image.png
中文大意

给我们n个点m条边每条边都有一个价值w对于边u,v{u,v}我们可以将边u,v{u,v}删除变成u,和v相邻的边或者v,与u相邻的边每次这个操作都会花费这条边的价值。这个操作可以无限次。问经历过多次操作后从点1到点n所花费的最小价值是多少\

解法
样例一
image.png
对于样例一我们可以发现只需要将232-3这条边移动到282-8再将121-2移动到&1-8&即可如下图

image.png
所以我们的最小花费是6+3=96+3=9
样例三

image.png
对于样例三我们是通过把252-5这条边移动6次最终变成181-8这条边我们所花费的价值最小为22(6+1)=15422*(6 + 1) = 154
通过样例一三我们不难猜测出最小花费就是将某一条边变成1n1-n这条边
但是1n1-n的连接有两种可能一种是先连接1u1-u再连接vnv-n然后连接1n1-n另一种是将边uvu-v变成关于点x的自环然后连接1x1-x xnx-n最后连接1n1-n
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;
}