1. 程式人生 > 實用技巧 >CF59E Shortest Path(BFS技巧)

CF59E Shortest Path(BFS技巧)

題意:

在Ancient Berland有nn座城市和mm條長度相同的雙向道路。城市從11到nn編號。根據一個古老的迷信說法,如果一個旅行者連續訪問了a_iaib_ibic_ici三座城市而不去拜訪其他城市,來自東方的神祕力量將使他遭受巨大的災害。傳說中一共有kk組這樣的城市,每個三元組都是有序的,這意味著你可以按照a_iaic_icib_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\n",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\n"); //for (int v:path) printf("%d ",v); }