您的位置:首页 > 其它

HDU 1595 find the longest of the shortest 【枚举删边 + 最短路】

2018-01-18 00:27 489 查看
传送门

// 题意: 删去图中的一条边问1-n的最短距离中最长的为多少.

// 思路: 删去的一条边那么一定1-n原先的最短距离中的某一条边, 所有我们直接暴力删去这些边就行啦. 然后每删去一条边我们就求下最短路去其中的max值就行了.

注: 删边最好的删法就是用矩阵存图, 这样删去一条边, 直接就是在矩阵中将其权值令为inf. 记住这种方法. 在数据量小的时候很好用. (vector没试过, 不过感觉还行?, 但是复杂度好像得不到优化.)

const int maxn = 1e3+5;
int g[maxn][maxn];
int dis[maxn], vis[maxn];
int pre[maxn];
int n, m;
int dij(int st, int flag) {
Fill(vis, 0);
for (int i = 1 ; i <= n ; i ++) {
if (g[st][i] != inf && i != st && flag) pre[i] = st;
dis[i] = g[st][i];
}
vis[st] = 1;
for (int i = 1 ; i <= n ; i ++) {
int minn = inf;
int v = -1;
for (int j = 1 ; j <= n ; j ++) {
if (!vis[j] && minn > dis[j]){
v = j; minn = dis[j];
}
}
if(v != -1) {
vis[v] = 1;
for (int j = 1 ; j <= n ; j ++) {
if (dis[j] > dis[v] + g[v][j]) {
dis[j] = dis[v] + g[v][j];
if (flag) pre[j] = v;
}
}
}
}
return dis
;
}
void solve()
{
while(cin >> n >> m ) {
for (int i = 1 ; i <= n ; i ++) {
for (int j = 1 ; j <= n ;j ++) {
if (i == j) g[i][j] = 0;
else g[i][j] = inf;
}
}
Fill(pre, -1);
for (int i = 1 ;  i <= m ; i ++) {
int u, v, w;
cin >> u >> v >> w;
g[u][v] = g[v][u] = min(w, g[u][v]);

}
dij(1, 1);
int ans = 0;
int tt = n;
while(pre[tt] != -1) {
int tmp = g[pre[tt]][tt];
g[pre[tt]][tt] = g[tt][pre[tt]] = inf;
ans = max(ans , dij(1, 0));
g[pre[tt]][tt] = g[tt][pre[tt]] = tmp;
tt = pre[tt];
}
cout << ans << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐