bzoj3694最短路
bzoj3694最短路
Description
给出一个n个点m条边的无向图,n个点的编号从1~n,定义源点为1。定义最短路树如下:从源点1经过边集T到任意一点i有且仅有一条路径,且这条路径是整个图1到i的最短路径,边集T构成最短路树。 给出最短路树,求对于除了源点1外的每个点i,求最短路,要求不经过给出的最短路树上的1到i的路径的最后一条边。
Input
第一行包含两个数n和m,表示图中有n个点和m条边。
接下来m行,每行有四个数ai,bi,li,ti,表示图中第i条边连接ai和bi权值为li,ti为1表示这条边是最短路树上的边,ti为0表示不是最短路树上的边。
Output
输出n-1个数,第i个数表示从1到i+1的要求的最短路。无法到达输出-1。
Sample Input
5 9
3 1 3 1
1 4 2 1
2 1 6 0
2 3 4 0
5 2 3 0
3 2 2 1
5 3 1 1
3 5 2 0
4 5 4 0
Sample Output
6 7 8 5
HINT
对于100%的数据,n≤4000,m≤100000,1≤li≤100000
solution
我的方法很诡异
首先删一条边相当于把一棵子树孤立出来。
那么答案应要通过其他边绕到子树外面的点,再回到根。
我们记d[i][j]表示以i为根的子树到其他点的最短路。
可以用类似树形dp的方法把儿子的信息合并上来。
O(n^2+m)
其他方法
考虑一条非树边,假设它连接了u,v
那么他可以贡献的段为u~lca,u~lca
树剖维护
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define maxn 4005
#define inf 1e9
using namespace std;
int n,m,t1,t2,t3,t4,head[maxn],tot=1;
int d[maxn][maxn],ans[maxn];
int dfst[maxn],dfsn[maxn],sc,len[maxn],flag[maxn];
struct node{
int v,nex,w,op;
}e[200005];
void lj(int t1,int t2,int t3,int t4){
e[++tot].v=t2;e[tot].w=t3;e[tot].op=t4;e[tot].nex=head[t1];head[t1]=tot;
}
void DFS(int k,int fa){
dfst[k]=++sc;
for(int i=head[k];i;i=e[i].nex){
if(!e[i].op||e[i].v==fa)continue;
len[e[i].v]=len[k]+e[i].w;
DFS(e[i].v,k);
}
dfsn[k]=sc;
}
void dfs(int k,int fa,int b){
for(int i=head[k];i;i=e[i].nex){
if(!e[i].op||e[i].v==fa)continue;
dfs(e[i].v,k,i);
}
for(int i=1;i<=n;i++)d[k][i]=inf;
for(int i=head[k];i;i=e[i].nex){
if(!e[i].op||e[i].v==fa)continue;
for(int x=1;x<=n;x++)d[k][x]=min(d[k][x],d[e[i].v][x]+e[i].w);
flag[e[i].v]=1;
}//合并子树
for(int i=head[k];i;i=e[i].nex){
if(i==(b^1))continue;
d[k][e[i].v]=min(d[k][e[i].v],e[i].w);
}// itself
int l=dfst[k],r=dfsn[k];
//cout<<"k: "<<k<<endl;
ans[k]=inf;
for(int x=1;x<=n;x++){
//cout<<d[k][x]<<' ';
if(dfst[x]<l||dfst[x]>r){
ans[k]=min(ans[k],d[k][x]+len[x]);
}
}//cout<<endl;
for(int i=head[k];i;i=e[i].nex){
flag[e[i].v]=0;
}
}
int main()
{
freopen("shortest.in","r",stdin);
freopen("shortest.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
lj(t1,t2,t3,t4);lj(t2,t1,t3,t4);
}
DFS(1,0);
//for(int k=1;k<=n;k++)cout<<k<<' '<<len[k]<<' '<<dfst[k]<<endl;
dfs(1,0,0);
if(ans[2]!=inf)printf("%d",ans[2]);
else printf("-1");
for(int i=3;i<=n;i++){
if(ans[i]==inf)printf(" -1");
else printf(" %d",ans[i]);
}
puts("");
return 0;
}
bzoj3694最短路的更多相关文章
- [bzoj3694]最短路_树链剖分_线段树
最短路 bzoj-3694 题目大意:给你一个n个点m条边的无向图,源点为1,并且以点1为根给出最短路树.求对于2到n的每个点i,求最短路,要求不经过给出的最短路树上的1到i的路径上的最后一条边. 注 ...
- [bzoj3694]最短路
Description 给出一个$n$个点$m$条边的无向图,$n$个点的编号从$1-n$,定义源点为$1$. 定义最短路树如下:从源点$1$经过边集$T$到任意一点$i$有且仅有一条路径,且这条路径 ...
- bzoj3694: 最短路(树链剖分/并查集)
bzoj1576的帮我们跑好最短路版本23333(双倍经验!嘿嘿嘿 这题可以用树链剖分或并查集写.树链剖分非常显然,并查集的写法比较妙,涨了个姿势,原来并查集的路径压缩还能这么用... 首先对于不在最 ...
- 「BZOJ3694」「FJ2014集训」最短路
「BZOJ3694」「FJ2014集训」最短路 首先树剖没得说了,这里说一下并查集的做法, 对于一条非树边,它会影响的点就只有u(i),v(i)到lca,对于lca-v的路径上所有点x,都可通过1-t ...
- 最短路 BZOJ3694 树链剖分+线段树
分析: 树剖裸题,[Usaco2009 Jan]安全路经Travel 的简化版 剖开最短路树,遍历每一条没在最短路树上的边. 这种情况下,有且仅有u到v路径上,出来lca之外的点能够通过这条边到达,并 ...
- [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)
[BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...
- bzoj1001--最大流转最短路
http://www.lydsy.com/JudgeOnline/problem.php?id=1001 思路:这应该算是经典的最大流求最小割吧.不过题目中n,m<=1000,用最大流会TLE, ...
- 【USACO 3.2】Sweet Butter(最短路)
题意 一个联通图里给定若干个点,求他们到某点距离之和的最小值. 题解 枚举到的某点,然后优先队列优化的dijkstra求最短路,把给定的点到其的最短路加起来,更新最小值.复杂度是\(O(NElogE) ...
- Sicily 1031: Campus (最短路)
这是一道典型的最短路问题,直接用Dijkstra算法便可求解,主要是需要考虑输入的点是不是在已给出的地图中,具体看代码 #include<bits/stdc++.h> #define MA ...
随机推荐
- Winform导入Excel数据到数据库
public partial class ImportExcel : Form { AceessHelpers accessHelper = new AceessHelpers(); public I ...
- Android_组件_Activity基础
一.概述 Activity是应用组件,提供了用户交互的窗口.一个应用由多个彼此联系的Activity组成.它大多数情况是全屏窗口显示,也可以作为悬浮窗口 或者 多窗口模式. 二.生命周期 下图是来自A ...
- swoole 连接池
proxy_pool.php <?php class ProxyServer { protected $frontends; protected $backends; /** * @var sw ...
- JS:字符串转成json数据,和json转成字符串方法 iframe获取父级传过来的数据
字符串转成json数据,和json转成字符串方法 //转为JSON adinfo=JSON.parse(adinfo) //转为字符串 adinfo=JSON.stringify(adinfo) 大概 ...
- STM32的四种输出模式(转载)
1.普通推挽输出(GPIO_Mode_Out_PP): 使用场合:一般用在0V和3.3V的场合.线路经过两个P_MOS 和N_MOS 管,负责上拉和下拉电流. 使用方法:直接使用 输出电平 ...
- 字符编码,ASCII、Unicode与UTF-8的理解
首先我们先要明白的两点是:1.计算机中的信息都是由二进制的0和1储存的:2.我们再计算机屏幕上看到的各种字符都是计算机系统按照一定的规则将二进制数字转换而来的. 一.基本概念. 1.字符集(chars ...
- mysql--timestamp加减
利用timestamp()对timestamp类型进行秒加减操作: 1.加10秒: 2.减10秒:
- border,border-width不支持百分比
1.border-width不支持百分比 原因:不会因为设备大就按比例变大 同样的,outline,box-shadow,text-shadow也不支持百分比 也就是border不支持百分比 2.bo ...
- 编程高手解读什么是NodeJs?
首先在搞清楚什么NodeJs之前,我们先来聊聊JavaScript,只要做过开发的人都应该知道JavaScript是目前最为流行的前端(客户端)脚 本语言,JavaScript在Web项目中的使用率可 ...
- 【Best Time to Buy and Sell Stock II】cpp
题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...