首页 > 代码库 > [luoguP1186] 玛丽卡(spfa)
[luoguP1186] 玛丽卡(spfa)
传送门
因为要随机删除一条边,而枚举所有边肯定会超时,经过发现,先求出一遍最短路,而要删除的边肯定在最短路径上,删除其他的边对最短路没有影响。
所以可以先求出最短路,再枚举删除最短路上的每一条边再求最短路。
——代码
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 6 using namespace std; 7 8 const int MAXN = 1001; 9 int n, m, cnt, ans, qu, qv;10 int head[MAXN], to[MAXN * MAXN], next[MAXN * MAXN], val[MAXN * MAXN], dis[MAXN], pre[MAXN];11 bool vis[MAXN], flag;12 queue <int> q;13 14 inline void add(int x, int y, int z)15 {16 to[cnt] = y;17 val[cnt] = z;18 next[cnt] = head[x];19 head[x] = cnt++;20 }21 22 inline void spfa(int u)23 {24 int i, v;25 while(!q.empty()) q.pop();26 memset(vis, 0, sizeof(vis));27 memset(dis, 127 / 3, sizeof(dis));28 q.push(u);29 dis[u] = 0;30 while(!q.empty())31 {32 u = q.front();33 q.pop();34 vis[u] = 0;35 for(i = head[u]; i != -1; i = next[i])36 {37 v = to[i];38 if((u == qu && v == qv) || (u == qv && v == qu)) continue;39 if(dis[v] > dis[u] + val[i])40 {41 dis[v] = dis[u] + val[i];42 if(!flag) pre[v] = u;43 if(!vis[v])44 {45 vis[v] = 1;46 q.push(v);47 }48 }49 }50 }51 }52 53 int main()54 {55 int i, x, y, z;56 scanf("%d %d", &n, &m);57 memset(pre, -1, sizeof(pre));58 memset(head, -1, sizeof(head));59 for(i = 1; i <= m; i++)60 {61 scanf("%d %d %d", &x, &y, &z);62 add(x, y, z);63 add(y, x, z);64 }65 spfa(1);66 flag = 1;67 for(i = n; i != -1; i = pre[i])68 {69 qu = i;70 qv = pre[i];71 spfa(1);72 if(dis[n] != 707406378) ans = max(ans, dis[n]);73 }74 printf("%d", ans);75 return 0;76 }
[luoguP1186] 玛丽卡(spfa)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。