ABOUT ME

Today
Yesterday
Total
  • [Baekjoon - 22443] Minus One
    문제 풀이/Baekjoon Online Judge 2023. 2. 13. 23:02

    난이도: Gold II

     

    태그

    더보기
    • Breadth-First Search
    • Combinatorics
    • Meat In the Middle (알고 있을 필요는 없지만, 뭔가 그런 느낌이 있다.)

     

    풀이

    1. 원래의 최단 경로를 알고 있을 때, 간선을 하나 추가한 뒤의 최단 경로는?

    더보기

    원래의 최단 경로를 [s=v0,v1,,vk=t]라고 하고, 추가된 간선을 x,y라고 합시다.

    그럼, 새로운 그래프의 최단 경로는 원래의 최단경로이거나, [s,,x,y,,t]라는 새로운 경로가 됩니다.

     

    d(v,w)v에서 w로 가는 최단 경로의 길이라고 하면,

    우리가 찾은 경로의 길이는 d(s,x)+1+d(y,t)가 됩니다.

     

    2. 간선을 추가한 뒤의 최단 경로가 이전의 최단 경로 - 1이 되려면?

    더보기

    d(s,x)+1+d(y,t)=k1이므로, d(s,x)+d(y,t)=k2여야 합니다.

     

    3. d(s,x)를 고정할 때, 가능한 경우는?

    더보기

    d(s,x)가 고정되면, d(y,t) 역시 고정됩니다.

    이 때의 경우의 수는 x를 고르는 경우의 수 × y를 고르는 경우의 수가 되고,

    x를 고르는 경우의 수는 d(s,x)를 만족하는 x의 개수가 됩니다.

    y 역시 비슷하게, d(y,t)를 만족하는 y의 개수가 되겠죠.

     

    4. 코드

    더보기
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    vector<int> adj[100020];
     
    int dis[2][100020];
    int num[2][100020];
    void bfs(int idx, int st){
        memset(dis[idx], -1sizeof(dis[idx])); dis[idx][st] = 0; num[idx][0+= 1;
        queue<int> q; q.push(st);
        while (!q.empty()){
            int now = q.front(); q.pop();
            for (int nxt : adj[now]){
                if (dis[idx][nxt] != -1){ continue; }
                dis[idx][nxt] = dis[idx][now]+1; num[idx][ dis[idx][nxt] ] += 1;
                q.push(nxt);
            }
        }
    }
     
    void Main(){
        int n, m, st, ed; cin >> n >> m >> st >> ed;
        while (m--){
            int v, w; cin >> v >> w;
            adj[v].push_back(w); adj[w].push_back(v);
        }
        bfs(0, st); bfs(1, ed);
        int d = dis[0][ed];
        ll ans = 0;
        //for (int i = 0; i <= n; i++){ cout << "NUM " << i << "   " << num[0][i] << ' ' << num[1][i] << endl; }
        for (int i = 0; i <= d-2; i++){
            ans += 1LL*num[0][i]*num[1][d-2 - i];
        }
        cout << ans;
    }
    cs
Designed by Tistory.