Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

鉄道運賃(Train Fare)

JOI 国には $N$ 個の都市があり，それぞれ $1, 2, ..., N$ の番号が付けられている．都市 1 はJOI 国の首都である．

また，JOI 国には鉄道会社がひとつだけあり，この会社は $M$ 個の路線を運行している．これらの路線にはそれぞれ $1, 2, ..., M$ の番号が付けられており，$i$ 番目 $(1 \leq i \leq M)$ の路線は都市 $U_i$ と都市 $V_i$ を双方向に結んでいる．都市と都市の間を鉄道以外で移動することはできない．また，どの都市からどの都市へもいくつかの路線を乗り継いで移動することができるようになっている．

現在，どの路線の運賃も 1 円である．経営不振に陥った鉄道会社は，今後 $Q$ 年間かけていくつかの路線の運賃を値上げする計画を立てた．この計画では，計画開始から $j$ 年目$(1 \leq j \leq Q)$ の年初めに路線 $R_j$ の運賃を 1 円から 2 円に値上げする予定である．値上げされた路線の運賃は，その後ずっと2 円のままであり，再び値上げすることはない．

ところで，この鉄道会社では，毎年，各都市の住民の満足度調査を行っている．計画開始前は，どの都市の住民もこの鉄道会社に満足しているが，値上げによって不満を持つ住民が現れる可能性がある．

それぞれの年の満足度調査は，その年の値上げの実施後に行う．したがって， $j$ 年目$(1 \leq j \leq Q)$ の満足度調査は，路線 $R_1, R_2, ... , R_j$ の運賃の値上げは完了し，それ以外の路線の運賃は値上げされていない状態で行われることになる． $j$ 年目$(1 \leq j \leq Q)$ の満足度調査では，都市 $k$ $(2 \leq k \leq N)$ の住民は，以下の条件が満たされるとき，そしてそのときに限り鉄道会社に不満を抱く．

その時の運賃で都市 $k$ から首都である都市 $1$ へ移動するときの費用の最小値が，計画開始前の運賃で都市 $k$ から都市 $1$ へ移動するときの費用の最小値よりも大きい．

ただし，いくつかの路線を使って移動するときの費用は，それぞれの路線の運賃の合計である．また，都市 $1$ の住民が鉄道会社に対して不満を抱くことはない．値上げ後の運賃で最小の費用を達成する経路は，計画開始前の運賃で最小の費用を達成する経路と異なる可能性があることに注意せよ．

計画の実行に先立って，今後 $Q$ 年間の住民の満足度調査それぞれにおいて，鉄道会社に不満を抱く住民がいる都市の数を計算しておきたい．

課題

JOI 国の鉄道路線の情報と，運賃の値上げ計画が与えられたとき，それぞれの満足度調査において鉄道会社に不満を抱く住民がいる都市の数を求めるプログラムを作成せよ．

入力

標準入力から以下の入力を読み込め．

1 行目には，3 個の整数 $N, M, Q$ が空白を区切りとして書かれている．これらは，JOI 国には $N$ 個の都市と $M$ 個の路線があり，運賃の値上げ計画が $Q$ 年間に渡ることを表している．

続く $M$ 行のうちの $i$ 行目$(1 \leq i \leq M)$ には，2 個の整数 $U_i$, $V_i$ が空白を区切りとして書かれている．これらは，$i$ 番目の路線が都市 $U_i$ と都市 $V_i$ を結んでいることを表している．

続く $Q$ 行のうちの $j$ 行目$(1 \leq j \leq Q)$ には，整数 $R_j$ が書かれている．これは，計画の $j$ 年目に路線 $R_j$ の運賃を値上げすることを表している．

出力

標準出力に $Q$ 行で出力せよ． $j$ 行目$(1 \leq j \leq Q)$ には， $j$ 年目の満足度調査で不満を抱く住民がいる都市の数を出力せよ．

制限

すべての入力データは以下の条件を満たす．

$2 \leq N \leq 100 000$

$1 \leq Q \leq M \leq 200 000$

$1 \leq U_i \leq N$ $(1 \leq i \leq M)$

$1 \leq V_i \leq N$ $(1 \leq i \leq M)$

$U_i \ne V_i$ $(1 \leq i \leq M)$

$1 \leq R_j \leq M$ $(1 \leq j \leq Q)$

$R_j \ne R_k$ $(1 \leq j < k \leq Q)$

どの2 つの都市についても，それらを直接結ぶ路線は 1 個以下である．

どの都市についても，その都市から都市 1 までいくつかの路線を使って移動することができる．

入出力例

入力例1

5 6 5
1 2
1 3
4 2
3 2
2 5
5 3
5
2
4
1
3

出力例1

0
2
2
4
4

この入力例では，計画開始前，及びそれぞれの満足度調査の時点でのそれぞれの都市から都市 $1$ への運賃は，以下の表のようになる．

時点

都市2    

都市3    

都市4    

都市5    

計画開始前     

1

1

2

2

1 年目

1

1

2

2

2 年目

1

2

2

3

3 年目

1

2

2

3

4 年目

2

2

3

3

5 年目

2

2

4

3

例えば，3 年目の満足度調査では，都市 $3$ と都市 $5$ の住民が不満を抱くので，出力の 3 行目には 2 を出力する．

入力例2

4 6 6
1 2
1 3
1 4
2 3
2 4
3 4
1
4
2
5
3
6

出力例2

1
1
2
2
3
3

入力例3

2 1 1
1 2
1

出力例3

1

第15回 日本情報オリンピック本選 課題   2016 年 2 月 14 日

Solution in C++14 (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(c) begin(c), end(c)
#define dump(x) cerr << __LINE__ << ":\t" #x " = " << (x) << endl

using Graph = vector<vector<pair<int,int>>>;

int n, m, q;
Graph g;
int d[100010];

int u[100010], v[100010];
int indeg[100010];

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);

    while(cin >> n >> m >> q){
        g.assign(n, {});
        rep(i, m){
            int &u = ::u[i], &v = ::v[i];
            cin >> u >> v;
            --u; --v;
            g[u].emplace_back(v, i);
            g[v].emplace_back(u, i);
        }

        queue<int> que;
        que.push(0);
        memset(d, 0x3f, sizeof d);
        memset(indeg, 0, sizeof indeg);
        d[0] = 0;
        while(que.size()){
            int v = que.front();
            que.pop();
            for(auto &e : g[v]){
                if(d[e.first] > d[v] + 1){
                    d[e.first] = d[v] + 1;
                    que.push(e.first);
                }
            }
        }

        Graph gg(n);
        rep(i, m){
            int &u = ::u[i], &v = ::v[i];
            if(abs(d[u] - d[v]) == 1){
                if(d[u] > d[v]) swap(u, v);
                gg[u].emplace_back(v, i);
                ++indeg[v];
            } else {
                u = v = -1;
            }
        }
        g = move(gg);

        int bad = 0;
        rep(qi, q){
            int r;
            cin >> r;
            --r;
            int &u = ::u[r], &v = ::v[r];
            if(u != -1){
                --indeg[v];
                if(indeg[v] == 0){
                    queue<int> que;
                    que.push(v);
                    while(que.size()){
                        int v = que.front();
                        que.pop();
                        if(indeg[v] == 0) ++bad;
                        rep(i, g[v].size()){
                            int dst = g[v][i].first, id = g[v][i].second;
                            --indeg[dst];
                            ::u[id] = ::v[id] = -1;
                            if(indeg[dst] == 0) que.push(dst);
                        }
                        g[v].clear();
                    }
                }
            }
            cout << bad << '\n';
        }
    }
}