Tranvía POJ-1847 El camino más corto, mapas mentales

Enlace de tema

POJ-1847

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

Supongo que te gusta

Origin blog.csdn.net/TheSunspot/article/details/107739760
Recomendado
Clasificación