题目描述:
解法一:
用邻接矩阵存储各地点的状态,然后dfs求出结果
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
bool vis[10010];
int w[10010][10010];
int n;
int sum = 0,MAX = 0;
void dfs(int s){
for(int i=1;i<=n;i++){
if(!vis[i]&&w[s][i]>0){
vis[i] = true;
sum+=w[s][i];
dfs(i);
vis[i] = false;
sum-=w[s][i];
}
}
if(sum>MAX){
MAX=sum;
}
}
int main(){
cin>>n;
for(int i = 1;i<=n-1;i++){
int a,b,c;
cin>>a>>b>>c;
w[a][b] = c;
w[b][a] = c;
}
for(int i=1;i<=n;i++){
vis[i] = true;
dfs(i);
vis[i] = false;
}
cout<<MAX*10+(MAX+1)*MAX/2;
return 0;
}
该方法存储空间不足
解法二:
用邻接表存储,在进行dfs
#include<cstring>
#include<algorithm>
#include<iostream>
int n;
typedef struct Node{
int data;
int dist;
struct Node* next;
}Node,*node;
node w[100010];
bool vis[100010];
int MAX=0,sum =0;
void dfs(int s){
node p = w[s]->next;
while(p){
if(!vis[p->data]){
vis[p->data] = true;
sum+=p->dist;
dfs(p->data);
sum-=p->dist;
vis[p->data] = false;
}
p = p->next;
}
if(MAX<sum){
MAX = sum;
}
}
void Add(int a,int b,int c){
if(w[a]==NULL){
w[a] = (node)malloc(sizeof (Node));
w[a]->next = NULL;
}
if(w[b] == NULL){
w[b] = (node)malloc(sizeof (Node));
w[b]->next = NULL;
}
node p1 = (node)malloc(sizeof (Node));
p1->data = b;
p1->dist = c;
p1->next = w[a]->next;
w[a]->next = p1;
node p2 = (node)malloc(sizeof (Node));
p2->data = a;
p2->dist = c;
p2->next = w[b]->next;
w[b]->next = p2;
}
using namespace std;
int main(){
cin>>n;
for(int i=1;i<=n-1;i++){
int a,b,c;
cin>>a>>b>>c;
Add(a,b,c);
}
for(int i=1;i<=n;i++){
vis[i] = true;
dfs(i);
vis[i] = false;
}
cout<<MAX*10+(MAX+1)*MAX/2;
return 0;
}
该方法会超时
解法三:
dfs两次,第一次找到一个离首都最远的点,第二次从最远的点开始,找到离其最远的点。
#include<cstring>
#include<algorithm>
#include<iostream>
int n;
typedef struct Node{
int data;
int dist;
struct Node* next;
}Node,*node;
node w[100010];
bool vis[100010];
long long MAX=0,sum =0,findx =0;
void dfs(int s){
node p = w[s]->next;
while(p){
if(!vis[p->data]){
vis[p->data] = true;
sum+=p->dist;
dfs(p->data);
sum-=p->dist;
vis[p->data] = false;
}
p = p->next;
}
if(MAX<sum){
MAX = sum;
findx = s;
}
}
void Add(int a,int b,int c){
if(w[a]==NULL){
w[a] = (node)malloc(sizeof (Node));
w[a]->next = NULL;
}
if(w[b] == NULL){
w[b] = (node)malloc(sizeof (Node));
w[b]->next = NULL;
}
node p1 = (node)malloc(sizeof (Node));
p1->data = b;
p1->dist = c;
p1->next = w[a]->next;
w[a]->next = p1;
node p2 = (node)malloc(sizeof (Node));
p2->data = a;
p2->dist = c;
p2->next = w[b]->next;
w[b]->next = p2;
}
using namespace std;
int main(){
cin>>n;
for(int i=1;i<=n-1;i++){
int a,b,c;
cin>>a>>b>>c;
Add(a,b,c);
}
vis[1] = true;
dfs(1);
vis[1] = false;
vis[findx] = true;
dfs(findx);
vis[findx];
cout<<MAX*10+(MAX+1)*MAX/2;
return 0;
}
总结:
通过这题,我学会了邻接表的存储方式,在我看来就是用于存储链表的数组。首先要定义一个结构体,用于存储地点,距离等,然后开出一个链表数组,下表就是起始地点。值得注意的是,使用头插法增加数据的,增加过程中要注意初始的数组中都是指向空的。要注意增加头节点。
记录一下