写在最前
在经历大一的一年学习后,发现卷课内绩点去保研并不适合我,在前两个学期的课内学习时间花得挺多的,最后出来的大一均绩3.1上下,目前在专业里排50%,但在大二大类分流之后会更加落后,索性及时改变方向。
家里的条件和个人原因我不适合出国,目前摆在面前的就是考研和就业两条路。考研网上都说是大三开始努力,为期一年,所以在现在就以考研为目标显然是不理智的,大二一年的时光不能被虚度,所以目前的打算安排就是 “尽可能” 兼顾二者作出的决定:
学好三大件:数据结构、计算机网络、操作系统 ; 学好英语:通过国外课程CS61B(正在进行) CS61C(未来) ;学好算法:去年一年断断续续地学,蓝桥杯拿了省二,今年再接再厉,争取进个国赛。
题目背景
高手最近谈恋爱了。不过是单相思。“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求。今天,这个阳光明媚的早晨,太阳从西边缓缓升起。于是它找到高手,希望在晨读开始之前和高手一起在鳌头山上一起散步。高手当然不会放弃这次梦寐以求的机会,他已经准备好了一切。
题目描述
鳌头山上有 n n n 个观景点,观景点两两之间有游步道共 m m m 条。高手的那个它,不喜欢太刺激的过程,因此那些没有路的观景点高手是不会选择去的。另外,她也不喜欢去同一个观景点一次以上。而高手想让他们在一起的路程最长(观景时它不会理高手),已知高手的穿梭机可以让他们在任意一个观景点出发,也在任意一个观景点结束。
输入格式
第一行,两个用空格隔开的整数 n n n 、 m . m. m. 之后 m m m 行,为每条游步道的信息:两端观景点编号、长度。
输出格式
一个整数,表示他们最长相伴的路程。
样例
样例输入
4 6
1 2 10
2 3 20
3 4 30
4 1 40
1 3 50
2 4 60
样例输出
150
提示
对于 100 % 100\% 100% 的数据: n ≤ 20 n \le 20 n≤20, m ≤ 50 m \le 50 m≤50,保证观景点两两之间不会有多条游步道连接。
开始思路
本题是在洛谷dfs中找的橙题,看上去比较人畜无害的模板题,通过book[ ]来记录每个景点有没有走过,把上一次结束的点last作为当前的起点去搜索,通过全局变量sum来记录路程。
初始代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=20+5;
int n,m,a[N],b[N],len[N],sum,ans;
bool book[N];
void dfs(int last){
bool judge=0;
for(int i=0;i<n;i++){
if(!book[i]){
judge=1;
break;
}
}
if(!judge){
ans=max(ans,sum);
return;
}
ans=max(ans,sum);
for(int i=0;i<m;i++){
if(!book[i]&&a[i]==last){
sum+=len[i];
book[i]=1;
dfs(b[i]);
book[i]=0;
sum-=len[i];
}
}
return;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=0;i<m;i++) cin>>a[i]>>b[i]>>len[i];
for(int i=0;i<n;i++){
book[i]=1;
dfs(i);
}
cout<<ans;
return 0;
}
反思
不能正确输出。本题不需要传统dfs的判断结束,因为如果没有空闲的点,那么自然就结束了;在主函数中的每次dfs(i)都要重置book[ ]数组,以免对下一次的dfs造成影响;本题是图,如果按现在做法,只能判断正向方向,因为每次都在a[ ]中找上次的last,所以要开二维数组存图
AC代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 20 + 5;
int n, m, a[N][N], ans;
bool book[N];
void dfs(int last, int sum) { //把全局变量sum改为了dfs的参数
ans = max(ans, sum);
for (int i = 1; i <= n; i++) {
if (!book[i] && a[last][i]) { //a[last][i]确保有这条路线,防止走成死胡同
book[i] = 1;
dfs(i, sum + a[last][i]);
book[i] = 0; //回溯
}
}
return;
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); //输入输出优化(算法竞赛必备)
cin >> n >> m;
for (int i = 0; i < m; i++) {
int x, y, z;
cin >> x >> y >> z;
a[x][y] = z; //二维数组存图
a[y][x] = z;
}
for (int i = 1; i <= n; i++) {
book[i] = 1;
dfs(i, 0);
memset(book, 0, sizeof(book)); //重置book[]数组
}
cout << ans;
return 0;
}