P2752 [USACO4.3]街道赛跑Street Race

这题也A了好久啊……(可能是我太菜了

看到这道题第一眼是懵的,但发现数据范围很小,稍微放轻松一些

第一题比较好解

首先我萌可以将必经之路这样理解:如果从起点到达终点必须经过它,辣么如果删掉这个点,这个图就不连通了!

因此我萌枚举每个点 进行bfs(对于点的删除处理方法很多,这里窝的方法是在bfs前就把该点的vis设为true,酱紫似乎很好写呢,也不会浪费时间复杂度)

----------------------------------------------------第一问完成分割线----------------------------------------------------------

看到第二题的第一反应就是符合条件的这些点必定都符合第一问!!

也没仔细想怎么证明就直接准备开始瞎搞了(毕竟这是一道 省选+/noi- 准备随便玩玩的。。。(泥萌可不能学我否则会和我一样刷题效率低的要死

然而谢天谢地我的rp终于回来了!!这个想法是对的

后来大概想了一下证明。符合第一问的点必定符合作为起点/终点的条件很好证明。必经了嘛。。所以肯定都能到。至于其他的点为什么不行。。。我也不太说得清楚啊!!(逃

但是!!但是!!坑点来了。终点不通往任何路口。第一遍54分就是坑在这个点QAQ(不过这个严格上说也不算坑点其实就是蒟蒻没有好好审题。。。。

 

那么如何保证没有公共点和公共边呢?有了前一问的基础,这题的解法就比较显然了。若图能被改点分成不连通的两个部分即为所求。

这段代码写的比较恶心。。。。详见注释

还有一个巨大的坑点!!这玩意儿可以有路通向自己!!最后一个点!!!(当然还有自环。)介个感觉题目里并没有说啊。。还是我眼瞎。。?

#include
using namespace std;

int n;
bool can[60][60];
vector edge[60];

bool vis[60];
bool before[60][60];//before[i][j]=true表示从起点到达终点的路径中i在j的前面 且该数组仅更新j为必经点的情况 详细用途见后

bool ok(int node) {
	queue q;//数组和队列勿忘初始化 要不然会出大事。。
	memset(vis,false,sizeof(vis));
	vis[0]=vis[node]=true;//先设为true这样bfs时就不会从这个点走
	before[0][node]=before[node][node]=true;//其实此处before数组可以完全替代vis
	q.push(0);
	while(!q.empty()){
		int cur=q.front();
		if (cur==n-1) return true;//即图仍连通
		vis[cur]=true;
		before[cur][node]=true;
		q.pop();
		for (int i=0;i q;
	memset(vis,false,sizeof(vis));
	q.push(0);
	while(!q.empty()){//bfs基本和先前类似
		int cur=q.front();
		if (cur==n-1) {
			for (int i=0;i>x;
			if (x==-1) {
				flag=true;
				break;
			}
			if (x==-2) break;
			if (x!=n) edge[n].push_back(x),can[n][x]=can[x][n]=true;
		}
		if (flag) break;
		n++;
	}
	vector ans;
	for (int i=1;i ans1;
	for (int i=0;i

 

你可能感兴趣的:(图论——搜索)