LA4080 删边求最短路
来源:互联网 发布:微信公众号淘宝优惠券 编辑:程序博客网 时间:2024/06/12 01:26
关键词:最短路树、删边重求最短路
删除任意一边,求新图任意两点最短路之和的最大值
1.建立每个点的最短路树
2.枚举删边,判断该边是否在最短路树中。在:删边后更改最短路树;不在:最短路树不变,即该点到任意一点的最短路不变
最短路树作用:删边问题中降低复杂度
原理:每个最短路树仅含n-1条边,降低了每个点的枚举量
每个最短路树中有n-1条边,还有删边属于k的最短路树时,才需要重新求k的最短路树,因此每个顶点最多求n-1次最短路树(即最短路),因此总共最多求n*(n-1)次最短路,复杂度O(n*n*m*logn)
技巧:1.用数组parent记录一棵树
2.链式前向星的好处:1)可以标记边。实现删边、标记特殊边的功能 2)无向图中可以找到任一条边的反向边(i^1是i的反向边)
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<vector>#include<stack>#include<queue>#define ll long long#define INF 0x3f3f3f3f#define maxn 110#define maxm 1010#define mem(a,b) memset(a,b,sizeof(a))using namespace std;int n,m;ll length;struct Edge{ int to,next; ll w;}edge[maxm<<2];int head[maxn],tot;ll d[maxn][maxn],dcopy[maxn][maxn];int parent[maxn][maxn],parentcopy[maxn][maxn];//i->j的单源最短路经;i最短路树中j的父节点bool cut[maxm<<2],vis[maxn];ll ans1,ans2;struct Heapnode{ int u; ll d; bool operator< (const Heapnode&rhs)const{ return d>rhs.d; }};void add(int u,int v,ll w){ edge[tot].to=v,edge[tot].next=head[u],edge[tot].w=w; head[u]=tot++;}void build(){ mem(cut,0),mem(head,-1),tot=0; for(int i=1;i<=m;i++){ int a,b; ll c; scanf("%d%d%lld",&a,&b,&c); add(a,b,c),add(b,a,c); }}void dij(int s,ll d[],int parent[]){ priority_queue<Heapnode> que; for(int i=1;i<=n;i++) d[i]=INF; d[s]=0,mem(vis,0),mem(parent,-1); que.push((Heapnode){s,0}); while(!que.empty()){ Heapnode x=que.top();que.pop(); int u=x.u; if(vis[u]) continue; vis[u]=1; for(int i=head[u];i!=-1;i=edge[i].next){ if(cut[i]) continue; int v=edge[i].to; ll w=edge[i].w; if(d[v]>d[u]+w){ d[v]=d[u]+w; parent[v]=u; que.push((Heapnode{v,d[v]})); } } }}ll cal(){ ll ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(d[i][j]==INF) ans+=length; else ans+=d[i][j]; return ans;}void Copyint(int a[][maxn],int b[][maxn]){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=b[i][j];}void Copyll(ll a[][maxn],ll b[][maxn]){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=b[i][j];}int main(){ //freopen("a.txt","r",stdin); while(scanf("%d%d%lld",&n,&m,&length)!=EOF){ build(); for(int i=1;i<=n;i++) dij(i,d[i],parent[i]); ans1=cal(),ans2=0; Copyll(dcopy,d),Copyint(parentcopy,parent);//记录原始数据 for(int u=1;u<=n;u++){ for(int i=head[u];i!=-1;i=edge[i].next){ cut[i]=cut[i^1]=1; int v=edge[i].to; ll w=edge[i].w; for(int k=1;k<=n;k++){ if((parent[k][v]==u)||(parent[k][u]==v)) { dij(k,d[k],parent[k]); }//如果<u,v>属于k的最短路树,重求最短路树 } ans2=max(ans2,cal()); Copyll(d,dcopy),Copyint(parent,parentcopy);//还原原始数据 cut[i]=cut[i^1]=0; } } printf("%lld %lld\n",ans1,ans2); }}
0 0
- LA4080 删边求最短路
- la4080 Warfare And Logistics 枚举+最短路
- UVA1416 Warfare And Logistics(LA4080)(最短路,5级)
- uva1410题解Warfare And Logistics(LA4080)(最短路)
- LA4080 Warfare And Logistics (dijkstra+最短路树)
- LA4080 Warfare And Logistics
- UVA1416 Warfare And Logistics(LA4080)
- 例题5.13 战争和物流 LA4080
- 短路
- 短路
- 短路
- 玛丽卡(spfa删边求最短路)
- 短路‘&’,‘|’vs不短路‘&&’,‘||’
- 短路或|| 短路与&&
- 最短路 & 次短路
- 短路 && 与||
- 短路容量
- 短路计算
- 24点计算问题
- RDIFramework.NET V2.8版本 ━ 开发实例之产品管理(WinForm)
- boost库生成文件命名和编译
- hdu 2527 Safe Or Unsafe(哈弗曼树)
- Java执行Shell遇到的各种问题
- LA4080 删边求最短路
- Linux kernel 的一个panic问题定位
- http请求幂等性
- lua注释
- 正则表达式,固话和手机号码验证,支持验证分机号
- js获取非行间样式/定义样式
- 安卓之Fragment详解
- IOS7.0 sizeWithFont:constrainedToSize:lineBreakMode:方法
- shell 修改xml文件 的参数值。