[ cf1407E ] 最短路+思维
E. Egor in the Republic of Dagestan
题意:n个点,m条边的有向图。从1号点出发到n号点。每个边有黑白两色,你需要对点染色,一点可以通过同色边到达另一点,求如何对所有点染色,使1到n的最短距离最大,或者根本不能到达?
题解:从n开始倒着bfs即可。如果第一次遇到某个点,则说明在真的最短路上,为了避免走这条路,我们将该点染成和连边相反的颜色即可。如果之后又遇到这个点则根据颜色来决定是否松弛,并加入队列。
#include
#define ll long long
#define pll pair
#define pii pair
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define mem0(x) memset(x,0,sizeof(x))
#define meminf(x) memset(x,0x3f,sizeof(x))
#define VI vector
#define VL vector
using namespace std;
const int N = 5e5+5;
int color[N], dis[N],vis[N];
vector> g(N);
queue q;
int main(){
ios::sync_with_stdio(0);
int n,m;cin>>n>>m;
rep(i,1,m){
int u,v,t;
cin>>u>>v>>t;
g[v].push_back({u,t});
}
meminf(dis);memset(color,-1,sizeof(color));
color[n] = dis[n] = 0;
q.push(n);
while(!q.empty()){
int v= q.front();q.pop();
vis[v] = 1;
for(auto&it :g[v]){
int u = it.first,t = it.second;
if(vis[u]) continue;
if(color[u]==-1){
color[u] = 1-t;
}else{
if(color[u]==t&&dis[u]>dis[v]+1){
dis[u] = dis[v]+1;
q.push(u);
}
}
}
}
int ans;
if(dis[1] == 0x3f3f3f3f){
ans = -1;
}else{
ans = dis[1];
}
cout<