牛客练习赛40——小A与欧拉路
https://ac.nowcoder.com/acm/contest/369/C
牛客练习赛27——水图
https://ac.nowcoder.com/acm/contest/188/C
好久没写博客了,临近放假,期末来了,最近在好好复习,没有好好写代码,好好填自己本学期上课没好好学的坑,这两道题都是tao哥推荐给我的,期末在即,总感觉他在害我,但还是没忍住做了做,算是图论题吧。
“水图”比“小A与欧拉路”,稍微简单点,“小A与欧拉路”算是“水图”的进化版,先说“水图”,给定起点,dfs找到从起点出发最长的一条路,答案只需要把除这条路的其他路都走两遍,这条路只走一遍即可。
“小A的欧拉路”,做法与“水图”相同,但是没有给定起点,所以需要先dfs找到一条最长的路,从这条路的终点出发再dfs一遍,同样答案也是把除这条路的其他路都走两遍,这条路只走一遍即可。
//小A的欧拉路
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 200500;
struct edge{
int v,x;
edge(int V,int X){
v = V;
x = X;
}
};
vector<edge>G[N];
int be = 0;
ll road = 0;
void dfs(int x,int fa,ll ans){
if(ans>road){
road = ans;
be = x;
}
for(int i=0;i < G[x].size();++i){
if(G[x][i].v != fa){
dfs(G[x][i].v,x,ans + G[x][i].x);
}
}
}
int main(){
int n;
scanf("%d",&n);
ll ans = 0;
for(int i = 1;i < n;++i){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
G[x].push_back(edge(y,z));
G[y].push_back(edge(x,z));
ans += z;
}
dfs(1,0,0);
road = 0;
dfs(be,0,0);
printf("%lld\n",ans * 2 - road);
return 0;
}
//水图
#include<stdio.h>
#include<vector>
using namespace std;
typedef long long ll;
const int N=50050;
struct edge{
int v,x;
edge(int X,int V){
x=X;
v=V;
}
};
vector<edge>G[N];
ll ss=0;
void dfs(int x,int fa,int an){
ss=max(ss,(ll)an);
for(int i=0;i<G[x].size();++i){
edge next = G[x][i];
int id = next.x;
if(id!=fa){
dfs(id,x,an+next.v);
}
}
}
int main(){
int n,x;
scanf("%d %d",&n,&x);
ll ans=0;
for(int i=1;i<n;++i){
int x,y,v;
scanf("%d %d %d",&x,&y,&v);
G[x].push_back(edge(y,v));
G[y].push_back(edge(x,v));
ans+=v;
}
dfs(x,-1,0);
printf("%lld\n",ans*2-ss);
return 0;
}