layout: post

title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

author: "luowentaoaa"

catalog: true

mathjax: true

tags:

- Dijkstra

- 最短路树

- 图论

- 训练指南


Warfare And Logistics

UVALive - 4080

题意

①先求任意两点间的最短路径累加和,其中不连通的边权为L ②删除任意一条边,求全局最短路径和的最大值

题解

刚看到题目是让各点之间的最短路径和,所以立马想到啦floyd算法求最短路,然后发现还要去掉一条边后求最短路中的最大值,则floyd会超时,所以打算用dijkstra+堆优化做,首先枚举n个顶点求各个顶点之间的最短路径,并求出最短路树,然后枚举每条边,如果这条边在最短路树中,则再求一遍该点的最短路径即可,如果不在最短路树中,则直接利用第一次求得最短路即可。

所谓的最短路树是指在求最短路的同时,记录最短路径并且标记那些点之间的连线有用到。

如果在枚举某个作为起点的时候这删去的点没有用到那就直接加上答案即可,这样时间就省去了一个m

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=100+10;
const int inf=1000000000;
struct Edge{
int from,to,dist;
};
struct HeapNode{
int d,u;
bool operator <(const HeapNode& rhs)const{
return d>rhs.d;
}
};
struct Dijkstra{
int n,m; ///点数和边数 点编号0~N-1
vector<Edge>edges; ///边列表
vector<int>G[maxn]; ///每个节点出发的边编号
bool done[maxn]; /// 是否已永久标号
int d[maxn]; /// s到各个点的距离
int p[maxn]; /// 最短路中的上一条边 void init(int n){
this->n=n;
for(int i=0;i<n;i++)G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int dist){ ///无向图调用两次
edges.push_back((Edge){from,to,dist});
m=edges.size();
G[from].push_back(m-1);
}
void dijkstra(int s){
priority_queue<HeapNode>Q;
for(int i=0;i<n;i++)d[i]=inf;
d[s]=0;
memset(done,0,sizeof(done));
Q.push((HeapNode){0,s});
while(!Q.empty()){
HeapNode x=Q.top();Q.pop();
int u=x.u;
if(done[u])continue;
done[u]=true;
for(int i=0;i<G[u].size();i++){
Edge& e=edges[G[u][i]];
if(e.dist>0&&d[e.to]>d[u]+e.dist){
d[e.to]=d[u]+e.dist;
p[e.to]=G[u][i];
Q.push((HeapNode){d[e.to],e.to});
}
}
}
}
}; Dijkstra solver;
int n,m,L;
vector<int>gr[maxn][maxn];
int used[maxn][maxn][maxn];
int idx[maxn][maxn];
int sum_single[maxn]; int compute_c(){
int ans=0;
memset(used,0,sizeof(used));
for(int src=0;src<n;src++){
solver.dijkstra(src);
sum_single[src]=0;
for(int i=0;i<n;i++){
if(i!=src){
int fa=solver.edges[solver.p[i]].from;
used[src][fa][i]=used[src][i][fa]=1;
}
sum_single[src]+=(solver.d[i]==inf?L:solver.d[i]);
}
ans+=sum_single[src];
}
return ans;
}
int compute_newc(int a,int b){
int ans=0;
for(int src=0;src<n;src++)
if(!used[src][a][b])ans+=sum_single[src];
else{
solver.dijkstra(src);
for(int i=0;i<n;i++)
ans+=(solver.d[i]==inf?L:solver.d[i]);
}
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
while(cin>>n>>m>>L){
solver.init(n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)gr[i][j].clear();
for(int i=0;i<m;i++){
int a,b,s;
cin>>a>>b>>s;a--;b--;
gr[a][b].push_back(s);
gr[b][a].push_back(s);
}
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)if(!gr[i][j].empty()){
sort(gr[i][j].begin(),gr[i][j].end());
solver.AddEdge(i,j,gr[i][j][0]);
idx[i][j]=solver.m-1;
solver.AddEdge(j,i,gr[i][j][0]);
idx[j][i]=solver.m-1;
}
int c=compute_c();
int c2=-1;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)if(!gr[i][j].empty()){
int &e1=solver.edges[idx[i][j]].dist;
int &e2=solver.edges[idx[j][i]].dist;
if(gr[i][j].size()==1)e1=e2=-1;
else e1=e2=gr[i][j][1];
c2=max(c2,compute_newc(i,j));
e1=e2=gr[i][j][0];
}
cout<<c<<" "<<c2<<endl;
}
return 0;
}

训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)的更多相关文章

  1. 训练指南 UVALive - 3126(DAG最小路径覆盖)

    layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...

  2. 训练指南 UVALive - 3415(最大点独立集)

    layout: post title: 训练指南 UVALive - 3415(最大点独立集) author: "luowentaoaa" catalog: true mathja ...

  3. 训练指南 UVALive - 3989(稳定婚姻问题)

    ayout: post title: 训练指南 UVALive - 3989(稳定婚姻问题) author: "luowentaoaa" catalog: true mathjax ...

  4. 训练指南 UVALive - 4043(二分图匹配 + KM算法)

    layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...

  5. 训练指南 UVALive - 5713(最小生成树 + 次小生成树)

    layout: post title: 训练指南 UVALive - 5713(最小生成树 + 次小生成树) author: "luowentaoaa" catalog: true ...

  6. 训练指南 UVALive - 3713 (2-SAT)

    layout: post title: 训练指南 UVALive - 3713 (2-SAT) author: "luowentaoaa" catalog: true mathja ...

  7. 训练指南 UVALive - 4287 (强连通分量+缩点)

    layout: post title: 训练指南 UVALive - 4287 (强连通分量+缩点) author: "luowentaoaa" catalog: true mat ...

  8. 训练指南 UVALive - 5135 (双连通分量)

    layout: post title: 训练指南 UVALive - 5135 (双连通分量) author: "luowentaoaa" catalog: true mathja ...

  9. 训练指南 UVALive - 3523 (双联通分量 + 二分图染色)

    layout: post title: 训练指南 UVALive - 3523 (双联通分量 + 二分图染色) author: "luowentaoaa" catalog: tru ...

随机推荐

  1. Netscaler工作流程

    Netscaler工作流程 http://blog.51cto.com/caojin/1898310 Citrix Netscaler有很多功能模块来满足应用交付的需求,为了能够做好的配置和排错工作, ...

  2. Notice : brew install php70

    To enable PHP in Apache add the following to httpd.conf and restart Apache: LoadModule php7_module  ...

  3. 【BZOJ 2006】[NOI2010]超级钢琴 ST

    我们先把所有最左端对应的最优右端入堆,eg: z  在[l,r](由题目给出的L,R决定)之间的最优解 y,然后出堆以后,再入堆z,y-1,z,y+1,那么我们只需要用st找最大前缀和就好了(ST是一 ...

  4. 【BZOJ 4832】 [Lydsy2017年4月月赛] 抵制克苏恩 期望概率dp

    打记录的题打多了,忘了用开维记录信息了......我们用f[i][j][l][k]表示已经完成了i次攻击,随从3血剩j个,2血剩l个,1血剩k个,这样我们求出每个状态的概率,从而求出他们对答案的贡献并 ...

  5. 2017福建省赛 FZU2272~2283

    1.FZU2272 Frog 传送门:http://acm.fzu.edu.cn/problem.php?pid=2272 题意:鸡兔同笼通解 题解:解一个方程组直接输出就行 代码如下: #inclu ...

  6. weblogic的安装和注意的问题以及在idea怎么用weblogic启动一个web服务

    第一步下载weblogic: 大家可以通过我的网盘下载weblogic,地址如下 https://pan.baidu.com/s/1NkZ_Gd-xfim5YGcdtjYoUw 第二步安装weblog ...

  7. socket编程 ------ BSD socket API

    伯克利套接字(Berkeley sockets),也称为BSD Socket.伯克利套接字的应用编程接口(API)是采用C语言的进程间通信的库,经常用在计算机网络间的通信. BSD Socket的应用 ...

  8. java,jenkins

    以前玩的是hudson ,现在玩的是jenkins.以前用的是Tomcat,现在不知道他们怎么不用... 1,装个Jenkins镜像. 2.配置项目: 先取个名字:exchange 配个svn: 构建 ...

  9. NET中IL理解(转)

    .NET CLR 和 Java VM 都是堆叠式虚拟机器(Stack-Based VM),也就是說,它們的指令集(Instruction Set)都是採用堆叠运算的方式:执行时的资料都是先放在堆叠中, ...

  10. codechef T4 IPC Trainers

    IPCTRAIN: 训练营教练题目描述 本次印度编程训练营(Indian Programming Camp,IPC)共请到了 N 名教练.训练营的日 程安排有 M 天,每天最多上一节课.第 i 名教练 ...