2023/3/19

这两段代码主要展示了在编程竞赛中如何利用图算法解决实际问题。L2-030题涉及判断两个个体是否有共同祖先,通过构建祖先关系并遍历判断;L3-022题则利用弗洛伊德算法求解最短路径,并根据路径建立新的边,进行深度优先搜索找出满足特定条件的路径。
摘要由CSDN通过智能技术生成

L2-030

在这里插入图片描述
对于该题而言姓是没有用的输入的时候只需要用姓来判断性别与祖先的名字然后就可以直接丢掉了
两人为异性的情况下,两个人的公共祖先都得在五代及以外只要有一个人祖先在五代以内就得输出No。所以得将一个人的祖先跑完去判断是否和另一个人的五代以内的祖先是同一个人(不死族属于是)。

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
map<string,string>fa;
map<string,bool>sx;
string ans(string n1,string n2){
	int i=1;
	for(string a=n1;a.length();i++,a=fa[a]){
		int j=1;
		for(string b=n2;b.length();j++,b=fa[b]){
			if(i>=5&&j>=5)break;
			if(a==b)return "No";
		}
	}
	return "Yes";
}
void slove(){
	int n;
	cin>>n;
	vector<string>a(n);
	for(auto &x:a){
		string y;
		cin>>x;
		cin>>y;
		int len=y.length();
		switch (y.back()) {
		case 'm':
			sx[x]=true;
			fa[x]="";
			break;
		case 'n':
			sx[x]=true;
			for(int i=1;i<=4;i++)y.pop_back();
			fa[x]=y;
			break;
		case 'f':
			sx[x]=false;
			fa[x]="";
			y.pop_back();
			break;
		case 'r':
			sx[x]=false;
			for(int i=1;i<=7;i++)y.pop_back();
			fa[x]=y;
			break;
		}
	}
	int q;
	cin>>q;
	while(q--){
		string n1,s1,n2,s2;
		cin>>n1>>s1>>n2>>s2;
		if(!sx.count(n1)||!sx.count(n2)){
			cout<<"NA"<<endl;continue;
		}
		if(sx[n1]==sx[n2]){
			cout<<"Whatever"<<endl;continue;
		}
		cout<<ans(n1,n2)<<endl;
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T=1;
//	cin>>T;
	while(T--){
		slove();
	}
	return 0;
}

L3-022在这里插入图片描述

n只有200所以可以建完边之后用弗洛伊德跑一遍最短路
对于每一个点i,使用得到的最短路更新mp[f[i][j]/k]=max(f[i][j],mp[f[i][j]/k])即同价钱的情况下可以跑的最远距离,在根据此建可以拍照的边,如果到了终点站(2端)也要拍照(建边)。
在建完拍照的边后跑一遍dfs后,输出答案。

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
//#define endl "\n"
typedef long long ll;
int n,m,k,st;
int vis[205];
bool ed[205];
int f[205][205];
vector<int>to[205];
void dfs(int x,const int&flag){
	vis[x]=flag;
	for(auto y:to[x]){
		if(vis[y]==flag)continue;
		dfs(y,flag);
	}
}
void slove(){
	memset(f,127,sizeof f);
	const int inf=f[0][0];
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++){
		int x,t,y;
		cin>>x;
		ed[x]=true;
		while(getchar()!='\n'){
			cin>>t>>y;
			f[x][y]=f[y][x]=min(f[x][y],t);
			x=y;
		}
		ed[x]=true;
	}
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				if(i==j||f[i][k]==inf||f[k][j]==inf)continue;
				f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
			}
		}
	}
	for(int i=1;i<=n;i++){
		map<int,int>mp;
		for(int j=1;j<=n;j++){
			if(f[i][j]==inf||f[i][j]<=mp[f[i][j]/k]||i==j)continue;
			mp[f[i][j]/k]=f[i][j];
		}
		for(int j=1;j<=n;j++){
			if(f[i][j]==mp[f[i][j]/k]||(f[i][j]!=inf&&ed[j]&&i!=j)){
				to[i].push_back(j);
		}
		}
	}
	int q;
	cin>>q;
	for(int i=1;i<=q;i++){
		cin>>st;
		dfs(st,i);
		bool p=false;
		for(int j=1;j<=n;j++){
			if(vis[j]!=i)continue;
			if(p)cout<<" ";
			else p=true;
			cout<<j;
		}
		cout<<endl;
	}
}
int main(){
//	ios::sync_with_stdio(false);
//	cin.tie(0);cout.tie(0);
	int T=1;
//	cin>>T;
	while(T--){
		slove();
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值