首先一遍Dijkstra求出S到每个点的最短路,并建出最短路图。

那么对于一条边,求在这条边不能使用的情况下,到首都S的最短时间会变长的点的数目,等价于求去掉这条边后在最短路图中不能从S出发到达的点的数目。

对于边x->y,新建一个点z,然后连边x->z->y,这样只需要计算从S到i上必须经过z的点数。

注意到最短路图是个DAG,我们可以按照拓扑序来建立必经点树:对于一个点x,它在必经点上的父亲为它所有前驱的lca,用倍增即可支持操作。

时间复杂度$O((n+m)\log n)$。

#include<cstdio>
typedef long long ll;
const int N=300010,M=400010,K=19;
const ll inf=1LL<<60;
int n,m,S,cnt,i,x,deg[N],g[N],v[M],w[M],nxt[M],ed;
int size[N],sum[N],id[N],h,t,q[N],dep[N],f[N][K],G[N],NXT[N],V[N];
ll d[N],ans[N];
struct E{int x,y,w;}a[M>>1];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void addedge(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
inline void add(int x,int y){deg[y]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void addtree(int x,int y){V[++ed]=y;NXT[ed]=G[x];G[x]=ed;}
struct PI{
ll x;int y;
PI(){}
PI(ll _x,int _y){x=_x,y=_y;}
inline PI operator+(PI b){return x<=b.x?PI(x,y):b;}
}val[262145];
void build(int x,int a,int b){
val[x]=PI(inf,a);
if(a==b)return;
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
}
inline void change(int x,int a,int b,int c,ll d){
if(a==b){val[x].x=d;return;}
int mid=(a+b)>>1;
c<=mid?change(x<<1,a,mid,c,d):change(x<<1|1,mid+1,b,c,d);
val[x]=val[x<<1]+val[x<<1|1];
}
inline int lca(int x,int y){
int i;
if(dep[x]<dep[y])i=x,x=y,y=i;
for(i=K-1;~i;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
if(x==y)return x;
for(i=K-1;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][0];
}
void dfs(int x){
for(int i=G[x];i;i=NXT[i])dfs(V[i]),size[x]+=size[V[i]];
sum[id[x]]=size[x];
}
int main(){
read(n),read(m);
for(i=1;i<=m;i++){
read(a[i].x),read(a[i].y),read(a[i].w);
addedge(a[i].x,a[i].y,a[i].w);
addedge(a[i].y,a[i].x,a[i].w);
}
read(S);
for(i=1;i<=n;i++)d[i]=inf;
build(1,1,n),change(1,1,n,S,d[S]=0);
while(val[1].x<inf)for(change(1,1,n,x=val[1].y,inf),i=g[x];i;i=nxt[i])if(d[x]+w[i]<d[v[i]])change(1,1,n,v[i],d[v[i]]=d[x]+w[i]);
for(ed=0,i=1;i<=n;i++)g[i]=0,size[i]=d[i]<inf;
for(cnt=n,i=1;i<=m;i++){
if(d[a[i].x]+a[i].w==d[a[i].y])id[++cnt]=i,add(a[i].x,cnt),add(cnt,a[i].y);
if(d[a[i].y]+a[i].w==d[a[i].x])id[++cnt]=i,add(a[i].y,cnt),add(cnt,a[i].x);
}
for(cnt++,i=1;i<cnt;i++)if(!deg[i])add(cnt,i);
q[h=t=1]=cnt,ed=0;
while(h<=t){
x=q[h++];
if(f[x][0])addtree(f[x][0],x);
for(dep[x]=dep[f[x][0]]+1,i=1;i<K;i++)f[x][i]=f[f[x][i-1]][i-1];
for(i=g[x];i;i=nxt[i]){
if(!f[v[i]][0])f[v[i]][0]=x;else f[v[i]][0]=lca(f[v[i]][0],x);
if(!(--deg[v[i]]))q[++t]=v[i];
}
}
dfs(cnt);
for(i=1;i<=m;i++)ans[a[i].x]+=sum[i],ans[a[i].y]+=sum[i];
for(i=1;i<=n;i++)printf("%lld\n",ans[i]);
return 0;
}

  

BZOJ4227 : 城市的更多相关文章

  1. 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】

    由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...

  2. 根据ip判断返回城市名称查询当地天气

    <?phpheader("content-type:text/html;charset=utf-8");date_default_timezone_set("Asi ...

  3. 使用page object模式抓取几个主要城市的pm2.5并从小到大排序后写入txt文档

    #coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...

  4. geolocation/ 百度地图api Geolocation 定位当前城市信息

    根据当前所处位置 定位所在城市信息 <html> <head> <meta charset="UTF-8" /> <title>js ...

  5. h5手机端下拉选择城市

    <!doctype html><html>    <head>            <meta http-equiv="Content-Type& ...

  6. BZOJ 2001: [Hnoi2010]City 城市建设

    2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1132  Solved: 555[Submit][ ...

  7. redis技巧--IP地址查询对应城市

    场景: 根据IP地址判断用户所在地,虽然网上有好多篇了,但我记录一个一看就懂的,不用看超长文字再自己理解了. 我们有城市和IP地址段的对应关系,如: 上海: 202.127.0.0 ~ 202.127 ...

  8. 美团HD(5)-选择城市

    DJSelectCityViewController.m #import "DJSelectCityViewController.h" #import "DJConsta ...

  9. 移动端城市选择JavaScript插件(基于WG的城市选择插件的修改版本)

    周末的时候趁着一次机会,拿WG(博客)开发的城市选择插件改了一个移动端可以直接用的城市选择插件. 原版插件是基于原声JavaScript写的,在此先感谢作者. 我做的只是依照肯德基注册会员的页面的交互 ...

随机推荐

  1. vue双向绑定原理分析

    当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/jiangzhenf ...

  2. Linux下JDK到底应该安装在哪儿?

    1 Linux 目录结构 即使这是个菜鸟级的问题,也经常难住老鸟.我就见过很资深的程序员把JDK不合适地安装到/home目录下.虽然不一定有最正确的安装位置,但一定有不适当的安装位置.为了确定我们到底 ...

  3. Replication监控及自动故障切换

    首先在相应的机器上增加授权 GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.108' IDENTIFIED BY 'repl';GRANT RE ...

  4. 各种initcall的执行先后顺序(module_init、postcore_initcall、arch_initcall、subsys_initcall、 fs_initcall)【转】

    转自:http://www.cnblogs.com/superlcc/archive/2012/09/12/2681930.html 现在以module_init为例分析initcall在内核中的调用 ...

  5. USB、UART、SPI等总线速率

    1. USB总线 USB1.1: ---低速模式(low speed):1.5Mbps ---全速模式(full speed): 12Mbps USB2.0:向下兼容.增加了高速模式,最大速率480M ...

  6. 对linux内核中jiffies+Hz表示一秒钟的理解

    jiffies在内核中是一个全局变量,它用来统计系统启动以来系统中产生的总节拍数,这个变量定义在include/linux/jiffies.h中,定义形式如下. unsigned long volat ...

  7. linux通过sendmail发送邮件

    安装sendmail: [root@li676-235 ~]# yum install sendmail 安装好后执行. [root@li676-235 ~]# /etc/init.d/sendmai ...

  8. ApiCloud利用NVTabBar模块快速搭建起APP的框架

    废话不说,直接上代码 模块地址:https://docs.apicloud.com/Client-API/Nav-Menu/NVTabBar 代码实例: <!doctype html> & ...

  9. React-Native 之 ListView使用

    前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...

  10. tomcat -> 简介&部署

    Tomcat 简介 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun和其他一些公司及个人共同开 ...