首先一遍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. bzoj千题计划272:bzoj4557: [JLoi2016]侦察守卫

    http://www.lydsy.com/JudgeOnline/problem.php?id=4557 假设当前到了x的子树,现在是合并 x的第k个子树 f[x][j] 表示x的前k-1个子树该覆盖 ...

  2. tweenMax学习笔记

    tweenMax是一款缓动插件,能实现很多牛逼的效果,在网上看了些demo,确实很吊,虽说很多用CSS3也能做出来,但是技多不压身,学之. 网上的demo还是很多的,但是资料不多,唯一能够让我有思绪的 ...

  3. li分两列显示

    只要控制了li的宽度,利用浮动就能实现<style type="text/css"> .my ul { width: 210px; } .my li { width: ...

  4. 【GDOI2018】所有题目和解题报告

    使用说明:题意和数据范围都只是回忆内容,仅供参考.题解陆续补上. Day 1 第一题 题意:给定n个数字,要求划分成k的连续段使得每个连续段内的数字之和相同,求最大的k.n,Σai<=10^6. ...

  5. 图的最短路径-----------SPFA算法详解(TjuOj2831_Wormholes)

    这次整理了一下SPFA算法,首先相比Dijkstra算法,SPFA可以处理带有负权变的图.(个人认为原因是SPFA在进行松弛操作时可以对某一条边重复进行松弛,如果存在负权边,在多次松弛某边时可以更新该 ...

  6. tf.Session()和tf.InteractiveSession()的区别

    官方tutorial是这么说的: The only difference with a regular Session is that an InteractiveSession installs i ...

  7. Strange Queries(莫队)

    题目 You are given an array with n integers a1, a2, ..., an, and q queries to answer. Each query consi ...

  8. 记录自己对EventLoop和性能问题处理的一点心得【转】

    转自:http://www.cnblogs.com/lanyuliuyun/p/4483384.html 1.EventLoop 这里说的EventLoop不是指某一个具体的库或是框架,而是指一种程序 ...

  9. 模板引擎--hogan

    学习地址:https://www.imooc.com/article/18493 Hogan的github地址镇楼:https://github.com/twitter/hogan.js

  10. Java基础92 MySQL插入当前系统时间

    1.时间格式 用yyyy表示年份(year). -- y  表示年的最后一位,yy 表示年的最后2位,yyy 表示年的最后3位,yyyy 用4位数表示年用MM表示月份(month).-- mm 用2位 ...