【codeforces gym】Increasing Costs
Description
给你一个\(n\)个点无重边无自环的无向连通图,每条边有一个边权,对于每一条边,询问去掉这条边之后有多少个点到\(1\)号点的最短路会发生改变
Solution
会用到一个叫做灭绝树的东西(这个名字好霸气qwq)
其实不算是什么特别高大上的玩意:灭绝树其实就是一个点灭绝后它的子树内的所有点都灭绝
然后所谓的“灭绝”其实可以理解为。。满足什么条件之类的,在不同的题目中有所不同(比如说在这题里面就是。。走不到)
然后这道题的话,因为是删边,我们可以将边也看成一个点
首先求出到\(1\)的最短路,然后对于原图中的一条边权为\(w\)的边\((i,j)\),如果说\(dis[j]=dis[i]+w\)的话,就在新图中连\((i,num)\)和\((num,j)\)的有向边,其中\(num\)表示的是这条边对应的节点
注意到如果说我们将一条边删掉,也就是相当于将这条边对应的节点\(num\)删掉,由于这条边删掉了,由这条边得到的最短路也就不能走了,对应到新图中就是\(num\)这个节点不能走到,接着那些的只能由它走到的后继也就不能走到了,以此类推
所以我们考虑用这样的方式建一棵树:我们将新图所有的边反过来建,然后对整个反过来的新图拓扑排序,从后往前处理每一个节点在树上面的\(fa\),那么处理到一个节点的时候,新图中所有能走到当前节点的点的\(fa\)都已经处理好了,然后我们将当前节点的\(fa\)设为所有能走到这个节点的那些点的\(lca\)
这样建完之后会发现,删掉一条边对应的点\(num\)之后不能走到的点其实就是其整个子树中的点
所以我们只要建出树之后计算一下每个节点的子树大小就好了
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=4e5+10,TOP=20;
const ll inf=1LL<<60;
struct xxx{
int y,nxt,id,dis;
}a[N*2];
struct Data{
int node;
ll dis;
Data(){}
Data(int node1,ll dis1){node=node1; dis=dis1;}
friend bool operator < (Data x,Data y){return x.dis>y.dis;}
};
priority_queue<Data> q;
queue<int> q1;
vector<int> pre[N];
int lis[N];
int h[N],f[N][TOP+1],dep[N];
ll dis[N];
int vis[N],d[N],sz[N];
int n,m,tot,S;
void add(int x,int y,int dis,int id){a[++tot].y=y; a[tot].nxt=h[x]; h[x]=tot; a[tot].id=id; a[tot].dis=dis;}
void print(vector<int> x){
for (int i=0;i<x.size();++i) printf("%d ",x[i]); printf("\n");
}
void dij(){
int u,v;
while (!q.empty()) q.pop();
for (int i=1;i<=n;++i) dis[i]=inf,vis[i]=false;
dis[S]=0;
q.push(Data(S,dis[S]));
while (!q.empty()){
v=q.top().node; q.pop();
if (vis[v]) continue;
vis[v]=1;
for (int i=h[v];i!=-1;i=a[i].nxt){
u=a[i].y;
if (vis[u]) continue;
if (dis[u]>dis[v]+a[i].dis){
dis[u]=dis[v]+a[i].dis;
q.push(Data(u,dis[u]));
}
}
}
for (int x=1;x<=n;++x){
for (int i=h[x];i!=-1;i=a[i].nxt){
u=a[i].y;
if (dis[u]==dis[x]+a[i].dis){
pre[u].push_back(a[i].id+n);
pre[a[i].id+n].push_back(x);
++d[a[i].id+n];
++d[x];
}
}
}
}
int get_lca(int x,int y){
if (!x||!y) return x+y;
if (dep[x]<dep[y]) swap(x,y);
for (int i=TOP;i>=0;--i)
if (dep[f[x][i]]>=dep[y]) x=f[x][i];
if (x==y) return x;
for (int i=TOP;i>=0;--i)
if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
void topo(int n){
int u,v;
while (!q1.empty()) q1.pop();
for (int i=1;i<=n;++i)
if (d[i]==0) q1.push(i);
lis[0]=0;
while (!q1.empty()){
v=q1.front(); q1.pop();
lis[++lis[0]]=v;
for (int i=0;i<pre[v].size();++i){
u=pre[v][i];
--d[u];
if (!d[u]) q1.push(u);
}
}
}
void get_fa(int x){
int lca,Sz=pre[x].size();
if (Sz==0){
f[x][0]=0;
}
else if (Sz==1)
f[x][0]=pre[x][0];
else if (Sz>=2){
lca=get_lca(pre[x][0],pre[x][1]);
for (int i=2;i<Sz;++i)
lca=get_lca(lca,pre[x][i]);
f[x][0]=lca;
}
for (int i=1;i<=TOP;++i) f[x][i]=f[f[x][i-1]][i-1];
dep[x]=dep[f[x][0]]+1;
sz[x]=(x<=n);
}
void solve(){
topo(n+m);
for (int i=lis[0];i>=1;--i)
get_fa(lis[i]);
for (int i=1;i<=lis[0];++i)
sz[f[lis[i]][0]]+=sz[lis[i]];
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x,y,z;
scanf("%d%d",&n,&m);
memset(h,-1,sizeof(h));
tot=0;
for (int i=1;i<=m;++i){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z,i);
add(y,x,z,i);
}
S=1;
dij();
solve();
//for (int i=1;i<=n+m;++i) printf("%d " ,f[i][0]); printf("\n");
for (int i=1;i<=m;++i)
printf("%d\n",sz[i+n]);
}
【codeforces gym】Increasing Costs的更多相关文章
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【Codeforces Gym 100725K】Key Insertion
Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...
- 【77.78%】【codeforces 625C】K-special Tables
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...
- 【15.07%】【codeforces 625A】Guest From the Past
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- 【codeforces 757C】Felicity is Coming!
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 750F】New Year and Finding Roots
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【13.77%】【codeforces 734C】Anton and Making Potions
time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【16.23%】【codeforces 586C】Gennady the Dentist
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【27.40%】【codeforces 599D】Spongebob and Squares
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
随机推荐
- 使用cors解决跨域遇到浏览器发出options嗅探
前言: 本地开发起的服务器,通过修改hosts文件设置域名映射到本地,接口在测试环境 1. 服务器端设置cors, 配置access-control-allow-origin 头部 使用蚂蚁金服的up ...
- Scrum Meeting 11 -2014.11.17
今天和其他两个小组讨论了关于整合问题,在数据库连接等具体方面上还需要继续商讨. 我们小组内部讨论了,这周还是需要在处理整合的同时做项目整体的测试与改进的. Member Today’s task Ne ...
- 实验一linux 系统简介和实验二基本概念及操作
作业 zy e
- 手机端学习助手的说明书需求以及团队PM选择
1.产品的背景 课堂上知识容量大.密度高,学生不能立刻掌握所学知识点,同时,网上资料冗杂繁复,指向性不强,导致学生不能高效的学习,为了充分利用学生的课余时间,培养学生自学能力,辅助老师教学,我们小组希 ...
- js一些常用方法总结
这两天开始在牛客网上做一些js在线编程,发现很多编程题其实调用的js方法都差不多一样,所以觉得可以汇总一下,方便记忆也可以多多熟悉. 1.slice()方法 这个方法就是可以从已有的数组中返回选定的元 ...
- Tuscany glossary of terms
SOA(service-oriented architecture) 面向服务的架构 解决问题:面向服务.多语言.多种数据格式.多协议 SCA(Service Component Architectu ...
- mac下搭建MySql环境基本步骤
准备工作做完后,开始: 创建数据库 step1: 在mac中->系统偏好设置->最下边点MySQL 在弹出页面中 关闭mysql服务(点击stop mysql server) step2: ...
- 软工网络15团队作业8——Beta阶段项目总结
1.新成员 姓名 风格 擅长 角色 宣言 李家俊 乱写 都有所涉猎 测试 混就完事了 丁树乐 潇洒 与人沟通 测试 与其临渊羡鱼,不如退而结网 2.是否需要更换团队的PM 不需要 3.下一阶段需要改进 ...
- jenkins构建启动失败
有一个项目,在启动的时候读取了环境变量,第一次写了一个启动脚本如下 #!/bin/bash --login jarFile=$ pid=`ps -ef | grep $jarFile | grep ' ...
- vi 基础配置
" Configuration file for vim " CVE-2007-2438 " Normally we use vim-extensions. If you ...