PAT A1139 First Contact DFS写法和简单写法

题目链接

这道题卡了好长时间, 有必要记录一下。
可以用DFS+剪枝来遍历求解, 没到下一层就减去一部分不合理的情况, 不会超时。如下:

//我的电脑上面用不了#include <bits/stdc++.h>
//DFS的剪枝条件一定要全面 DFS全局变量最好是计数 千万不要是索引 不要过度使用
//id 一定要用 %04d 这样的形式输出
//还有0000 和 -0000 的区别 这个真有点坑
#include <cstdio>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxN=10010;
struct Node{
	int first,second;
};
bool cmp(Node a, Node b){
	if (a.first!=b.first) return a.first<b.first;
	else return a.second<b.second;
}
vector<int> adj[maxN];
int n,m,k;
int isGirl[maxN]={0};
vector<Node> path;
int start, ed;
int first,second;
void DFS(int u, int depth){
	if (depth==2){
		if (u==ed || isGirl[u]!=isGirl[start]){
			return;
		}
		first=u;
	}
	if (depth==3){
		if (u==start || isGirl[u]!=isGirl[ed]){
			return;
		}
		second=u;
	}
	if (depth==4){
		if (u!=ed){
			return;
		}
		path.push_back(Node{first, second});
		return;
	}
	for (int i=0; i<adj[u].size(); i++){
		int v=adj[u][i];
		if (v!=u) DFS(v,depth+1);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	for (int i=0; i<m; i++){
		string u,v;
		cin>>u>>v;
		int absu=abs(stoi(u));
		int absv=abs(stoi(v));
		adj[absu].push_back(absv);
		adj[absv].push_back(absu);
		if (u[0]=='-') isGirl[absu]=1;
		if (v[0]=='-') isGirl[absv]=1;
	}	
	scanf("%d",&k);
	for (int i=0; i<k; i++){
		scanf("%d %d",&start, &ed);
		start=abs(start);
		ed=abs(ed);
		path.clear();
		DFS(start, 1);
		printf("%d\n",path.size());
		sort(path.begin(), path.end(), cmp);
		for (int j=0; j<path.size(); j++){
			printf("%04d %04d\n",path[j].first, path[j].second);
		}
	}
}

还有一种更简单的方法, 因为这道题条件特殊, 只通过两个中介,所以可以找起始点的同性朋友, 终止点的同性朋友, 然后看他们两是不是朋友, 是朋友说明他们两就可以作为中介。 是不是朋友可以用一个二维数组来表示。 这种方法的思路很简单, 而且理论上说速度应该很快,但是空间会很大(通过map 映射处理的话, 空间会很小, 但是评测有16M 的空间, 怎么搞都不会用到这么大的空间)。

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxN=10010;
struct Node{
	int first,second;
};
bool cmp(Node a, Node b){
	if (a.first!=b.first) return a.first<b.first;
	else return a.second<b.second;
}
int n,m,k;
vector<int> adj[maxN];
int rel[maxN][maxN]={0};
vector<Node> path;
int isGirl[maxN]={0};
int main(){
	scanf("%d %d",&n, &m);
	for (int i=0; i<m; i++){
		string u,v;
		cin>>u>>v;
		int absU=abs(stoi(u));
		int absV=abs(stoi(v));
		if (u[0]=='-') isGirl[absU]=1;
		if (v[0]=='-') isGirl[absV]=1;
		adj[absU].push_back(absV);
		adj[absV].push_back(absU);
		rel[absU][absV]=rel[absV][absU]=1;
	}
	scanf("%d",&k);
	for (int i=0; i<k; i++){
		int start, ed;
		scanf("%d %d",&start, &ed);
		start=abs(start);
		ed=abs(ed);
		path.clear();
		for (int j=0; j<adj[start].size(); j++){
			int u=adj[start][j];
			if (u!=ed && isGirl[u]==isGirl[start]){
				for (int p=0; p<adj[ed].size(); p++){
					int v=adj[ed][p];
					if (v!=start && isGirl[v]==isGirl[ed]){
						if (rel[u][v]){
							path.push_back(Node{u,v});
						}
					}
				}
			}
		}
		sort(path.begin(), path.end(), cmp);
		printf("%d\n",path.size());
		for (int j=0; j<path.size(); j++){
			printf("%04d %04d\n",path[j].first, path[j].second);
		}
	}
}

理论上说,这种解法应该很快, 但实际上最后一组数据有时候会超时。用DFS解法的话, 应该比较慢, 但实际上很快,最后一组数据一定不会超时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值