Enlace de tema
Título
Dados n nodos, hay caminos entre los nodos, pero cada nodo tiene un interruptor, y solo el nodo al que apunta el interruptor puede pasar. Puede mover el interruptor. Dados el punto de inicio y el punto final, encuentre el número mínimo de veces para mover el interruptor.
solución
Construya un gráfico Para cada nodo, el nodo con el que está alineado el conmutador inicial está conectado al borde, y el peso es 0, lo que significa que no se necesita ningún conmutador para pasar a través de este borde. Para los bordes de otros nodos de enlace, el peso es 1, lo que significa que el conmutador debe conmutarse a través de este borde. Ejecute la ruta más corta desde el punto de inicio hasta el punto final, y la matriz de distribución encontrará el número mínimo de veces para mover el interruptor.
Código
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
#include<cstdio>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
using namespace std;
typedef long long ll;
const int maxn=550;
const int maxe=5050;
const int inf=0x3f3f3f3f;
struct Edge{
int v,w,next;
}edge[maxe];
int head[maxn],cnt;
bool vis[maxn];
int in[maxn];
int dis[maxn];
int n,m;
void init(){
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int u,int v,int w){
edge[cnt].v=v;
edge[cnt].next=head[u];
edge[cnt].w=w;
head[u]=cnt;
cnt++;
}
bool spfa(int s) {
memset(vis,0,sizeof(vis));
memset(in,0,sizeof(in));
memset(dis,0x3f,sizeof(dis));
queue<int>q;
q.push(s);
vis[s]=true;
in[s]++;
dis[s]=0;
while(q.size()) {
int p=q.front();q.pop();
vis[p]=false;
for(int i=head[p];i!=-1;i=edge[i].next) {
//SPFA
int v=edge[i].v;
if(dis[v]>edge[i].w+dis[p]) {
dis[v]=edge[i].w+dis[p];
in[v]++;
if(in[v]>=n)
return true;//这个点更新了多于n次,说明存在负环
if(!vis[v]) {
vis[v]=true;
q.push(v);
}
}
}
}
return false;
}
int main(){
IOS
init();
int s,t;
cin>>n>>s>>t;
for(int i=1;i<=n;i++){
int tmp,v;
cin>>tmp;
if(!tmp)
continue;
tmp--;
cin>>v;
add(i,v,0);
while(tmp--){
cin>>v;
add(i,v,1);
}
}
spfa(s);
if(dis[t]!=inf)
cout<<dis[t]<<endl;
else
cout<<"-1"<<endl;
}