1139 First Contact (30分)(深度优先遍历)

题目传送门
Unlike in nowadays, the way that boys and girls expressing their feelings of love was quite subtle in the early years. When a boy A had a crush on a girl B, he would usually not contact her directly in the first place. Instead, he might ask another boy C, one of his close friends, to ask another girl D, who was a friend of both B and C, to send a message to B – quite a long shot, isn’t it? Girls would do analogously.

Here given a network of friendship relations, you are supposed to help a boy or a girl to list all their friends who can possibly help them making the first contact.

Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers N (1 < N ≤ 300) and M, being the total number of people and the number of friendship relations, respectively. Then M lines follow, each gives a pair of friends. Here a person is represented by a 4-digit ID. To tell their genders, we use a negative sign to represent girls.

After the relations, a positive integer K (≤ 100) is given, which is the number of queries. Then K lines of queries follow, each gives a pair of lovers, separated by a space. It is assumed that the first one is having a crush on the second one.

Output Specification:
For each query, first print in a line the number of different pairs of friends they can find to help them, then in each line print the IDs of a pair of friends.

If the lovers A and B are of opposite genders, you must first print the friend of A who is of the same gender of A, then the friend of B, who is of the same gender of B. If they are of the same gender, then both friends must be in the same gender as theirs. It is guaranteed that each person has only one gender.

The friends must be printed in non-decreasing order of the first IDs, and for the same first ones, in increasing order of the seconds ones.
解题思路:
对于A和B,将整个图的关系用邻接表来存放,首先遍历A的所有朋友,找到与A同性且不是B的,记录为C;再遍历C的朋友,找出与B同性且不是B的,记录为D。再遍历D的朋友,若在D的邻接表中可找到B,那么即将C,D存放在结果数组中,整个3层的DFS遍历结束后,按照题意sort排序一下输出即可。
首先注意
题目中的坑:
1.由于存在0000与-0000的情况存在,对于people number的存放不能单纯用int正负来判断,必须用string类型,可判断其长度或者首字符是否是‘-’来判断男女;
2.输出时注意加上%04d;

代码一稿:(又臭又长,推荐看2稿)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
struct node{
	int value,type;//type=0,male;type=1,female
	node(int _value,int _type){
		value=_value;
		type=_type;
	}
};
struct kuai{
	int a,b;
};
vector<kuai>u[105];
vector<node>v[maxn];
int vis[maxn],idx=0;
vector<int>res(2);
bool compare(kuai k1,kuai k2){
	if(k1.a==k2.a)
		return k1.b<k2.b;
	else
		return k1.a<k2.a;
}
void dfs(int a,int b,int ta,int tb,int ceng){
	if(ceng==3){
		for(int i=0;i<v[a].size();i++){
			int value=v[a][i].value;
			if(!vis[value]){
				if(value==b){
					kuai ku={res[0],res[1]};
					u[idx].push_back(ku);
				}
			}
		}
	}else{
		for(int i=0;i<v[a].size();i++){
			int value=v[a][i].value;
			if(!vis[value]&&value!=b){
				if(ceng==1){
					if(v[a][i].type==ta){
						res[0]=value;
						vis[value]=1;
						dfs(value,b,ta,tb,ceng+1);
						vis[value]=0;
					}
				}else if(ceng==2){
					if(v[a][i].type==tb){
						res[1]=value;
						vis[value]=1;
						dfs(value,b,ta,tb,ceng+1);
						vis[value]=0;
					}
				}
			}
		}
	}
}
int main(){
	freopen("in.txt","r",stdin);
	int n,m,k;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int a,b,ta=0,tb=0;
		string s1,s2;
		s1.clear();
		s2.clear();
		s1.resize(5);
		s2.resize(5);
		scanf("%s %s",&s1[0],&s2[0]);
		if(s1[0]=='-'){
			a=stoi(s1.substr(1,4));
			ta=1;
		}else a=stoi(s1);	
		if(s2[0]=='-'){
			b=stoi(s2.substr(1,4));
			tb=1;
		}else b=stoi(s2);
		v[a].push_back(node(b,tb));
		v[b].push_back(node(a,ta));
	}
	cin>>k;
	for(int i=0;i<k;i++){
		fill(vis,vis+maxn,0);
		int a,b,ta=0,tb=0;
		string s1,s2;
		s1.clear();
		s2.clear();
		s1.resize(5);
		s2.resize(5);
		scanf("%s %s",&s1[0],&s2[0]);
		if(s1[0]=='-'){
			a=stoi(s1.substr(1,4));
			ta=1;
		}else a=stoi(s1);	
		if(s2[0]=='-'){
			b=stoi(s2.substr(1,4));
			tb=1;
		}else b=stoi(s2);
		vis[a]=1;
		dfs(a,b,ta,tb,1);
		sort(u[idx].begin(),u[idx].end(),compare);
		int num=u[idx].size();
		cout<<num<<endl;
		for(int j=0;j<num;j++){
			printf("%04d %04d\n",u[idx][j].a,u[idx][j].b);
		}
		idx++;
	}
	return 0;
}

代码二稿:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
struct kuai{
	int a,b;
};
vector<kuai>u;
vector<int>v[maxn];
int sex[maxn];//0为男,1为女 
int vis[maxn];
vector<int>res(2);
bool compare(kuai k1,kuai k2){
	return k1.a==k2.a?k1.b<k2.b:k1.a<k2.a;
}
void dfs(int a,int b,int type[],int ceng){
	for(int i=0;i<v[a].size();i++){
		int value=v[a][i];
		if(ceng==2&&value==b){
			kuai ku={res[0],res[1]};
			u.push_back(ku);
		}else{
			if(!vis[value]&&value!=b&&sex[value]==type[ceng]){
				res[ceng]=value;
				vis[value]=1;
				dfs(value,b,type,ceng+1);
				vis[value]=0;
			}
		}
	}
}
int main(){
	freopen("in.txt","r",stdin);
	int n,m,k;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int a,b,ta=0,tb=0;
		string s1,s2;
		s1.clear();
		s2.clear();
		s1.resize(5);
		s2.resize(5);
		scanf("%s %s",&s1[0],&s2[0]);
		if(s1[0]=='-'){
			a=stoi(s1.substr(1,4));
			sex[a]=1;
		}else a=stoi(s1);	
		if(s2[0]=='-'){
			b=stoi(s2.substr(1,4));
			sex[b]=1;
		}else b=stoi(s2);
		v[a].push_back(b); v[b].push_back(a);
	}
	cin>>k;
	for(int i=0;i<k;i++){
		u.clear();
		fill(vis,vis+maxn,0);
		int a,b,ta=0,tb=0;
		scanf("%d %d",&a,&b);
		int type[2]={0,0};
		a=a<0?-a:a; b=b<0?-b:b;
		type[0]=sex[a];type[1]=sex[b];
		vis[a]=1;//容易疏漏 
		dfs(a,b,type,0);
		sort(u.begin(),u.end(),compare);
		cout<<u.size()<<endl;
		for(int j=0;j<u.size();j++){
			printf("%04d %04d\n",u[j].a,u[j].b);
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值