題解:
先用跑一次最短路,記錄每個點的所有最短路的入度節點,以及會給別的節點造成最短路的出度,然後呢就是每次每次改邊就是將深度大的那個點減去深度小的入度,如果有個點沒有了入度就ans++,然後再去修改他的所有出度;
#include<bits/stdc++.h>
using namespace std;
int d[100020];
int vis[100020];
set<int>rd[200020];
priority_queue<pair<int,int> >qq;
int head[100020];
int next[400040];
int ver[400040];
set<int>mapa[100020];
int n,m,q,tot,ans;
int read(){
int num=0;
char ch=getchar();
while(ch>'9'||ch<'0'){
ch=getchar();
}
while(ch>='0'&&ch<='9'){
num=(num<<1)+(num<<3)+ch-'0';
ch=getchar();
}
return num;
}
void add(int x,int y){
ver[++tot]=y;
next[tot]=head[x];
head[x]=tot;
}
void bfs(int u){
qq.push(make_pair(0,u));
while(qq.size()){
int x=qq.top().second;
qq.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=next[i]){
if(d[ver[i]]==d[x]+1){
mapa[x].insert(ver[i]);
rd[ver[i]].insert(x);
continue;
}
if(d[ver[i]]>d[x]+1){
d[ver[i]]=d[x]+1;
for(set<int>::iterator it=rd[ver[i]].begin();it!=rd[ver[i]].end();it++){
mapa[*it].erase(ver[i]);
}
rd[ver[i]].clear();
rd[ver[i]].insert(x);
mapa[x].insert(ver[i]);
qq.push(make_pair(-d[ver[i]],ver[i]));
}
}
}
}
void check(int x){
if(!rd[x].size()){
if(vis[x]) return;
vis[x]=1;
ans++;
while(mapa[x].size()){
rd[*mapa[x].begin()].erase(x);
check(*mapa[x].begin());
mapa[x].erase(mapa[x].begin());
}
}
}
int main(){
n=read(),m=read(),q=read();
for(int i=2;i<=n;i++) d[i]=500000;
for(int i=1;i<=m;i++){
int x=read(),y=read();
add(x,y);
add(y,x);
}
bfs(1);
for(int i=1;i<=n;i++) vis[i]=0;
for(int i=1;i<=q;i++){
int x=read(),y;
x*=2;
if(d[ver[x]]>d[ver[x-1]]){
y=ver[x-1];
x=ver[x];
}
else {
y=ver[x];
x=ver[x-1];
}
if(rd[x].find(y)!=rd[x].end()){
rd[x].erase(y);
}
if(rd[y].find(x)!=rd[y].end()){
rd[y].erase(x);
}
check(x);
printf("%d\n",ans);
}
}