一本通 3.4.1 图的遍历
Posted xuqw11111
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一本通 3.4.1 图的遍历相关的知识,希望对你有一定的参考价值。
图的遍历
1341:【例题】一笔画问题
【题目描述】
如果一个图存在一笔画,则一笔画的路径叫做欧拉路,如果最后又回到起点,那这个路径叫做欧拉回路。
根据一笔画的两个定理,如果寻找欧拉回路,对任意一个点执行深度优先遍历;找欧拉路,则对一个奇点执行dfs,时间复杂度为O(m+n),m为边数,n是点数。
【题目分析】
定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点。
定理2:存在欧拉回路的条件:图是连通的,有0个奇点。
对每个点进行深搜,并对搜到的点进行计数count,如果count==n,则该路径为欧拉路 使用深搜可以记录路径并将路径倒着输出
【代码实现】
#include<bits/stdc++.h>
#define N 1005
using namespace std;
int f[N][N];
int s[N];
int b[N];
int n, m;
int t = 0;
void dfs(int z)
for (int i = 1; i <= n; i++)
if (f[z][i] == 1)
f[z][i] = f[i][z] = 0;
dfs(i);
b[t++] = z;
int main()
//定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点。
//定理2:存在欧拉回路的条件:图是连通的,有0个奇点。
cin >> n >> m;
for (int i = 1; i <= m; i++)
int x, y;
cin >> x >> y;
f[x][y] = f[y][x] = 1;
s[x]++;
s[y]++;
int flag = 1;
for (int i = 1; i <= n; i++)
if (s[i] % 2 == 1)
flag = i;
dfs(flag);
for (int i = 0; i < t; i++)
cout << b[i] << " ";
return 0;
1374:铲雪车(snow)
【题目描述】
随着白天越来越短夜晚越来越长,我们不得不考虑铲雪问题了。整个城市所有的道路都是双车道,因为城市预算的削减,整个城市只有1辆铲雪车。铲雪车只能把它开过的地方(车道)的雪铲干净,无论哪儿有雪,铲雪车都得从停放的地方出发,游历整个城市的街道。现在的问题是:最少要花多少时间去铲掉所有道路上的雪呢?
【题目分析】
问题的本质:坐标点连接的欧拉回路
问题的求解:所有道路长度求和,并乘2得到总距离,根据速度求出时间,小时和分钟均为整数,分钟采用四舍五入
【代码实现】
#include <bits/stdc++.h>
using namespace std;
int main()
long long int x, y;
// clock_t s = clock();
cin >> x >> y;
long long int x1, y1, x2, y2;
double sum = 0;
while (cin >> x1 >> y1 >> x2 >> y2)
sum += sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
double ans = sum * 2 / 20 / 1000;
long long int h = (int)ans;
long long int m = (int)((ans - h) * 60 + 0.5);
cout << h << ":" << setfill('0') << setw(2) << m;
// cout << endl << "the time cost is:" << clock() - s << endl;
return 0;
1375:骑马修栅栏(fence)
【题目描述】
农民John每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。
John是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个一个栅栏。你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次。John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。
每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点)。一个顶点上可连接任意多(≥1)个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。
你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。我们如果把输出的路径看成是一个500进制的数,那么当存在多组解的情况下,输出500进制表示法中最小的一个 (也就是输出第一个数较小的,如果还有多组解,输出第二个数较小的,等等)。 输入数据保证至少有一个解。
【题目分析】
特别的:两个顶点可能连接多个栅栏,节点的编号信息不确定
数据存储:读入每一条边,使用邻接矩阵进行记录,两点的连接信息记录边的数量,统计最大节点的标号n
搜索准备:确定起点start,从1到n枚举每个点的度,找到奇数度的点,如果没有从1开始找存在连接关系的最小节点
深度搜索:对起点start进行深度优先搜索,并将搜索节点信息存入数组,最后反向打印节点信息
【代码实现】
#include <bits/stdc++.h>
using namespace std;
#define N 2005
int edge[N][N];
int n, m;
int du[N];
int pos, circle[N];
void dfs(int cur)
circle[++pos] = cur;
for (int i = 1; i <= n; i++)
if (edge[cur][i])
edge[cur][i]--;
edge[i][cur]--;
dfs(i);
// break;
int main()
//input data
cin >> m;
for (int i = 1; i <= m; i++)
int x, y;
cin >> x >> y;
edge[x][y]++;
edge[y][x]++;
du[x]++, du[y]++;
n = max(n, max(x, y));
// clock_t s = clock();
int start = 0;
for (int i = 1; i <= n; i++)
if (du[i] % 2 == 1)
start = i;
break;
if (start == 0)
for (int i = 1; i <= n; i++)
if (du[i])
start = i;
break;
dfs(start);
for (int i = 1; i <= pos; i++)
cout << circle[i] << endl;
//output time
// cout << endl << clock() - s << endl;
return 0;
loj10151. 「一本通 5.1 练习 2」分离与合体
思路:
注意初始化dp[i][i]=0,输出顺序时层序遍历。
#include<cstdio> #include<iostream> #include<string> #include<queue> using namespace std; const int maxn = 310; void qread(int &x){ x = 0; register int ch = getchar(); if(ch < ‘0‘ || ch > ‘9‘) ch = getchar(); while(ch >= ‘0‘ && ch <= ‘9‘) x = 10 * x + ch - 48, ch = getchar(); } int data[maxn]; int n; int dp[maxn][maxn]; int sum[maxn]; int pos[maxn][maxn]; queue<pair<int, int> > qu; void show(int l, int r){ if(l == r) return ; cout << pos[l][r] << " "; qu.push(make_pair(l, pos[l][r])); qu.push(make_pair(pos[l][r] + 1, r)); while(!qu.empty()){ int a = qu.front().first, b = qu.front().second; qu.pop(); show(a, b); } } int main(void){ qread(n); for(int i = 1; i<=n; ++i){ qread(data[i]); dp[i][i] = 0; sum[i] = sum[i-1] + data[i]; } for(int L = 1; L < n; ++L) for(int i = 1; i + L <= n; ++i){ int j = i + L; dp[i][j] = 0; for(int k = i; k < j; ++k){ int t = dp[i][k] + dp[k + 1][j] + (data[i] + data[j]) * data[k]; if(t > dp[i][j]){ dp[i][j] = t; pos[i][j] = k; } } } printf("%d ", dp[1][n]); show(1, n); }
以上是关于一本通 3.4.1 图的遍历的主要内容,如果未能解决你的问题,请参考以下文章