https://codeforces.com/contest/1407/problem/E
玄学题,有一个重要的事情,反向建边,边指向的点颜色一致,那就从n开始bfs,第一次遇到必定要和边反色,因为不反色的话路就短了。。。(第一次遇到的路一定是最短的)
具体看代码,写法简单,参考LDK神仙
#include<iostream> #include<cstring> #include<queue> #include<vector> using namespace std; typedef long long ll; const int maxn = 5e5+111; ll dis[maxn]; ll INF = 1e17; struct Node{ int p,len; Node(int a,int b):p(a),len(b){} }; vector<Node>G[maxn]; void add(int x,int y,int len){ G[x].push_back(Node(y,len)); } int vis[maxn]; int n,m; int bfs(){ queue<int>que; que.push(n); dis[n] = 0; while(que.size()){ int x = que.front(); que.pop(); for(int i=0;i<G[x].size();i++){ int p =G[x][i].p; if(vis[p] == -1){//不标记就被抢先了 vis[p] = G[x][i].len^1; } else{ if(G[x][i].len == vis[p]){//送过来 if(dis[p] > dis[x] + 1){ dis[p] = dis[x] + 1; que.push(p); } } } } } return 0; } int main(){ cin>>n>>m; for(int i=0;i<=n;i++){ vis[i] = -1; dis[i] = INF; } for(int i=0;i<m;i++){ int x,y,len; cin>>x>>y>>len; if(x == y) continue; add(y,x,len);//指向即为颜色 } bfs(); if(dis[1] == INF){ cout<<-1<<endl; } else{ cout<<dis[1]<<endl; } //cout<<dis[1]<<endl; vis[n] = 1; for(int i=1;i<=n;i++){ if(vis[i] == -1) vis[i] = 1; cout<<vis[i]; } cout<<endl; return 0; }