2019ACM陕西省省赛题目笔记 #1 B题
B - Grid with Arrows ZOJ-4127
- 第一次思考:有向 哈密顿图–>欧拉图–>半欧拉图
- 一开始打算存每个点出度入读,最后判断 出度比入读大一的点的数量和入度比出度大一的点的数量。以上是比赛中的想法,然后发现没有考虑基图连通的问题。于是该题WA掉。
- 第二次思考:看题解(失去梦想)
- 题解将问题简化了,重新剖析一遍题目。得到了比半欧拉图更简单的结论(事实上我当时是有往这面思考的放弃的原因我想不起来了)
- 题意要求要有一条经过所有点的链。因为点数与边数相同并且每个点出度不大于1。所以满足题意的图只有两种形式:
- 1 以入度为0的点为起点有一条经过所有点的链,结尾点可指向任意处
- 2 全图只有一个环,且该环经过所有的点。
图示:稍后补 以后补 算了不补了
- 代码
/* * 主线:
* 1.存数据
* 2.判断入度为0的点:
* 2.1 0个 任取一点开始dfs一定能遍历所有点,否则不符题意
* 2.2 1个 从该点开始dfs一定能遍历所有点,否则不符题意
* 2.3 2个及以上 一定不符题意
* 3.开始dfs判断dfs记录的最大长度length是否和点的数目相同
* 4.数据还原
* */
//这个程序还可以简化一些完全没有必要的步骤
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<vector>
#define it i*m+j //数据保证 n*m<1e6 且长宽不定,所以就用一维数组存数据,弄一个it方便之后写
using namespace std;
const int N = 1e6+7;//数组下标上界
struct node{
int in;
int out;
}poi[N]; //存放每个点的出入度 我现在突然有了新思路:仔细一想觉得没必要 转行:
//可以在录数据的时候顺便判断出入度,但这样是不全面的
//针对不符题意的个例有点点效果,效果不大
int point[N]; //存dfs图,因为出度一定不大于1,并且不需要判断基图联通啥的,所以就这个数组足够
char map[N]; //存方向的字符串地图 题目把方向和数完全分开,所以很蛋疼。其实
//现在想想 其实可以都存在point[N]里面。
int vis[N+1]; //dfs标记数组,标记是否访问过
int length = 1; //记录dfs最大长度(深度)
int k; //点总数,用于dfs时比较
int bfs(int dep,int po) {
vis[po] = 1;