洛谷P7551 [COCI 2020/2021 #6] Alias 题解

本题做法

  • Dijkstra最短路+离散化思想。

思路

这其实是一道 Dijkstra 最短路的裸题,只需要对于每一次询问做一次 Dijkstra 然后判断输出即可。

这题有意思的点在于它的编号不是数字而是字符串,我们在这种情况下可以使用离散化思想,将每一个字符串通过 map 映射到一个唯一的数字上,然后使用这个映射值进行编号、运算。

代码

#include<bits/stdc++.h>

using namespace std;

const int INF=0x7f;
const double EPS=1e-8;
const int N=1e3+5;
const int M=1e3+5;

struct edge{
	int next;
	long long dis;
	int to;
} g[M];

struct node{
	long long dis;
	int pos;
	bool operator<(const node b)const{
		return b.dis<dis;
	}
};

int n,m,q,tots,tote,pre[N],dis[N];
bitset<N> vis;
map<string,int> mp;

void dijkstra(int st){
	for(int i=1;i<=tots;i++) dis[i]=INF;
	vis.reset();
	node cur={0,st};
	priority_queue<node> q;
	q.push(cur);
	dis[st]=0;
	while(!q.empty()){
		cur=q.top();
		q.pop();
		int x=cur.pos;
		if(vis[x]) continue;
		vis[x]=1;
		for(int i=pre[x];i;i=g[i].next){
			int y=g[i].to;
			if(dis[y]>dis[x]+g[i].dis||dis[y]==INF){
				dis[y]=dis[x]+g[i].dis;
				if(!vis[y]) q.push({dis[y],y});
			}
		}
	}
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		string x,y;
		int t;
		cin>>x>>y>>t;
		if(mp.find(x)==mp.end()){
			mp[x]=++tots;
		}
		if(mp.find(y)==mp.end()){
			mp[y]=++tots;
		}
		g[++tote].dis=t;
		g[tote].next=pre[mp[x]];
		g[tote].to=mp[y];
		pre[mp[x]]=tote;
	}
	cin>>q;
	while(q--){
		string a,b;
		cin>>a>>b;
		if(mp.find(a)==mp.end()||mp.find(b)==mp.end()) {
			cout<<"Roger"<<endl;
			continue;
		}
		dijkstra(mp[a]);
		if(dis[mp[b]]==INF){
			cout<<"Roger"<<endl;
		}else{
			cout<<dis[mp[b]]<<endl;
		}
	}
	return 0;
}
posted @ 2025-05-14 22:47  2789617221guo  阅读(6)  评论(0)    收藏  举报