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\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); }