-
Two
- POJ - 1849
- 有一颗n个结点的带权的无向树, 在s结点放两个机器人, 这两个机器人会把树的每条边都走一遍, 但是最后机器人不要求回到出发点. 问你两个机器人走的路总长之和的最小值是多少?
- 思路:每个机器人从起始点出发去遍历所有点,只有沿着直径走然后非直径边走两遍即可,结果就是所有,边权总和*2-直径,因为总有一条路然后沿着路走路两边的分叉访问回到道路上的过程会遍历两遍。所以这条路选择直径是最优的情况。即便是最初他们在非直径点上他们两个同时出发到达直径的过程中非直径边就相当与走了两遍,
-
#include<vector> #include<queue> #include<cstdio> #include<cstring> using namespace std; struct node { int v,w; }; #define maxn 100086 vector<node>edge[maxn]; bool vis[maxn]; int dis[maxn],ans; int bfs(int x) { memset(dis,0,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int>q; q.push(x); vis[x]=1; int po=0; while(!q.empty()) { int top=q.front(); q.pop(); if(dis[top]>ans) { ans=dis[top]; po=top; } for(int i=0; i<edge[top].size(); i++) { node temp=edge[top][i]; if(vis[temp.v]==0) { vis[temp.v]=1; dis[temp.v]=dis[top]+temp.w; q.push(temp.v); } } } return po; } int main() { int n,m,x,y,z; while(scanf("%d%d",&n,&m)==2) { int sum=0; for(int i=1; i<n; i++) { scanf("%d%d%d",&x,&y,&z); edge[x].push_back((node) { y,z }); edge[y].push_back((node) { x,z }); sum+=z; } ans=0; int point=bfs(m); ans=0; bfs(point); printf("%d\n",sum*2-ans); for(int i=1; i<=n; i++) edge[i].clear(); } return 0; }
Two POJ - 1849-树直径
最新推荐文章于 2019-09-25 18:43:00 发布