CF59E Shortest Path(BFS技巧)

题意:

在Ancient Berland有nn 座城市和mm 条长度相同的双向道路。城市从11 到nn 编号。根据一个古老的迷信说法,如果一个旅行者连续访问了a_iai 、b_ibi 、c_ici 三座城市而不去拜访其他城市,来自东方的神秘力量将使他遭受巨大的灾害。传说中一共有kk 组这样的城市,每个三元组都是有序的,这意味着你可以按照a_iai 、c_ici 、b_ibi 这样的方式来访问一组城市而不遭受灾害。Vasya想要从城市11 走到城市nn 并且不受到诅咒。请告诉他最短路的长度,并输出一条路线。

题解:

以边为单位做BFS,数据卡了set,过的极其艰难的一题,不得不说CF上2000分的题确实是超出我的水平很多,无论是思维强度还是代码能力。

#include<bits/stdc++.h>
using namespace std;
const int maxn=3005;
const int inf=1e9;
int n,m,k;
vector<int> g[maxn];
vector<int> st[3005][3005];
int d[3005][3005];
int pre[3005][3005];
struct qnode {
    int u,v;
}; 
void dfs (int u) {
    vector<int> path;
    printf("%d
",d[u][n]);
    printf("1 ");
    int t1=n,t2;
    while (t1!=1) {
        path.push_back(t1);
        t2=u;
        u=pre[u][t1];
        t1=t2;
    }
    reverse(path.begin(),path.end());
    for (int v:path) printf("%d ",v);
}
int judge (int a,int b,int c) {
    for (int v:st[a][b]) if (v==c) return 0;
    return 1;
}
void bfs (int s) {
    queue<qnode> q;
    q.push({0,s});
    while (!q.empty()) {
        qnode tt=q.front();
        q.pop();
        int u=tt.v;
        if (u==n) {
            dfs(tt.u);
            exit(0);
        }
        for (int v:g[u]) {
            if (d[u][v]==0&&judge(tt.u,u,v)) {
                d[u][v]=d[tt.u][u]+1;
                pre[u][v]=tt.u;
                q.push({u,v});
            }
        }
    }
}

int main () {
    scanf("%d%d%d",&n,&m,&k);
    for (int i=1;i<=m;i++) {
        int x,y;
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for (int i=1;i<=k;i++) {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        st[a][b].push_back(c);
    }
    bfs(1);
    printf("-1
");
    //for (int v:path) printf("%d ",v);
}
原文地址:https://www.cnblogs.com/zhanglichen/p/13510098.html