あなたの方法を見つけることNOIP 2014

説明

右側がある\(1 \)は、有向グラフ、リングから複数のエッジが存在してもよいです。

始点から終点までの最短経路を求め、経路上の全ての点を満足する点は、エンドポイントと直接または間接的に通信するエッジ点です。

ゲームはこの問題を作ったときは、気持ちが良い道路のタイトルです。

溶液

安全な特殊なリング、一見無関係な文をすることができ文を読み出します。

まず、裏面を構築、端から歩き始め、エンドポイントにどのポイントを得ることができます。

暴力は、それが最後に到達することができ、すべてのポイントの側面を指すのだパスに参加することはできません各点について計算します。

次いで、エッジの重みに応じて\(1 \) 最短BFS正当点で実行。

ディープ検索が+ BFS前処理建て逆の側面を達成するために使用することができ、立ち往生書き込みリングであることが判明。

そのため、検索DFSあらかじめメモリと同様に、BFSを変更することを検討してください。

コード

#include <bits/stdc++.h>
using namespace std;
#define re register
#define F first
#define S second
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const int N = 1e4 + 5, M = 2e5 + 5;
int read() {
    int x = 0, f = 0; char ch = 0;
    while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
    return f ? -x : x;
}
struct edge{
    int to, nxt;
}e[M];
int head[M], tot, dis[N];
void addedge(int x, int y){
    e[++tot].to = y; e[tot].nxt = head[x]; head[x] = tot;
}
int start[N], to[N];
bool can[N], allcan[N], vis[N];
int main(){
    int n = read(), m = read();
    for (int i = 1; i <= m; i++){
        int x = read(), y = read();
        start[i] = x; to[i] = y;
        if (x != y) addedge(y, x);
    }
    int s = read(), t = read();
    queue <int> q; q.push(t); 
    while (!q.empty()){
        int x = q.front(); q.pop(); can[x] = 1;
        for (int i = head[x]; i; i = e[i].nxt){
            int y = e[i].to;
            if (!vis[y]){
                vis[y] = can[y] = 1;
                q.push(y);
            }
        }
    }
    memset(head, 0, sizeof(head)); memset(vis, 0, sizeof(vis)); tot = 0;
    for (int i = 1; i <= m; i++)
        if (start[i] != to[i]) addedge(start[i], to[i]);
    for (int x = 1; x <= n; x++) {
        allcan[x] = can[x];
        for (int i = head[x]; i; i = e[i].nxt) 
            allcan[x] &= can[e[i].to];
    }
        
    if (allcan[s]) q.push(s), vis[s] = 1;
    while (!q.empty()){
        int x = q.front(); q.pop();
        if (x == t){
            printf("%d\n", dis[t]);
            return 0;
        }
        for (int i = head[x]; i; i = e[i].nxt){
            int y = e[i].to;
            if (allcan[y] && !vis[y]){
                vis[y] = 1; q.push(y);
                dis[y] = dis[x] + 1;
            }
        }
    }
    puts("-1");
    return 0;
}

おすすめ

転載: www.cnblogs.com/lyfoi/p/11443375.html