JZOJ 5959. 【NOIP2018模擬11.8A組】鐵路運輸
阿新 • • 發佈:2019-01-22
題目大意
有張n個點,m條邊的圖,設dis[i]為1到i的最短路徑。
第i次修改,將某條邊的邊權從1變成2。
求i次修改後,有多少個i的dis[i]變了。
題解
考慮最短路是怎麼一步步求出來的。
考慮最經典的spfa。
最後能夠搞出一個拓撲圖。(比賽的時候一條拓撲圖的邊被計算很多很多次)
在拓撲圖上不考慮刪邊,而是給邊賦權。
那麼一個點i的dis[i]最後什麼時候改變?這個時間就是從1到i所有拓撲序列的路徑權值的最大值。
定義路徑權值:這條路徑的邊的最小權值。
直接拓撲排序即可。
危險資訊
DIJ+堆優化打錯了。必須找出原因。
程式碼
#include<iostream>
#include <cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 100010
#define M 200010
#define P(a) putchar(a)
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
struct note{
int to,next,id;
}edge[M<<1],edge1[M<<1];
int p[M];
int head[N],tot;
int head1[N],tot1;
int dis[N],dis1[N];
int n,m,q,i,j,k,ans[M];
int qu[N*10],ql,qr,COL;
int u,v,wz,xin;
int weight[M],outd[N];
int bz[N];
bool bz1[M];
int read(){
int fh=0,rs=0;char ch=0;
while((ch<'0'||ch>'9')&&(ch^'-'))ch=getchar ();
if(ch=='-')fh=1,ch=getchar();
while(ch>='0'&&ch<='9')rs=(rs<<3)+(rs<<1)+(ch^'0'),ch=getchar();
return fh?-rs:rs;
}
void write(int x){
if(x>9)write(x/10);
P(x%10+'0');
}
void lb1(int x,int y,int z){
edge1[++tot1].to=y;
edge1[tot1].next=head1[x];
edge1[tot1].id=z;
head1[x]=tot1;
}
void lb(int x,int y,int z){
edge[++tot].to=y;
edge[tot].next=head[x];
edge[tot].id=z;
head[x]=tot;
}
void spfa0(){
int i,x,w;
dis[1]=0;
fo(i,2,n)dis[i]=2139062143;
qr=1,ql=0;
qu[1]=1;
while(ql<qr){
x=qu[++ql];
for(i=head[x];i;i=edge[i].next){
if(dis[edge[i].to]>dis[x]+1){
dis[edge[i].to]=dis[x]+1;
qu[++qr]=edge[i].to;
}
}
}
}
void sou(){
int i,x;
fo(x,1,n){
for(i=head[x];i;i=edge[i].next)
if(dis[edge[i].to]==dis[x]+1){
bz1[edge[i].id]=1;
lb1(x,edge[i].to,edge[i].id);
outd[edge[i].to]++;
}
}
}
void dye(){
int i,x;
qu[qr=1]=1;ql=0;
bz[1]=COL;
xin=1;
while(ql<qr){
x=qu[++ql];
for(i=head1[x];i;i=edge1[i].next)
if(bz1[edge1[i].id]&&(bz[edge1[i].to]^COL)){
qu[++qr]=edge1[i].to;
bz[edge1[i].to]=COL;
xin++;
}
}
}
int main(){
n=read();m=read();q=read();
fo(i,1,m){
u=read(),v=read();
lb(u,v,i);lb(v,u,i);
weight[i]=2139062143;
}
fo(i,1,q)p[i]=read();
spfa0();
fo(i,1,n)bz[i]=0;
sou();
fo(i,1,q)weight[p[i]]=i;
qu[qr=1]=1,ql=0;
dis1[1]=q+1;
while(ql<qr){
u=qu[++ql];
for(i=head1[u];i;i=edge1[i].next){
outd[edge1[i].to]--;
dis1[edge1[i].to]=Max(dis1[edge1[i].to],Min(dis1[u],weight[edge1[i].id]));
if(!outd[edge1[i].to]){
qu[++qr]=edge1[i].to;
}
}
}
sort(dis1+1,dis1+n+1);
fo(i,1,n){
ans[dis1[i]]=ans[dis1[i-1]]+1;
}
fo(i,1,q)ans[i]=Max(ans[i],ans[i-1]);
fo(i,1,q)write(ans[i]),P('\n');
return 0;
}