题目链接
D. Eternal Victory
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Valerian was captured by Shapur. The victory was such a great one that Shapur decided to carve a scene of Valerian’s defeat on a mountain. So he had to find the best place to make his victory eternal!
He decided to visit all n cities of Persia to find the best available mountain, but after the recent war he was too tired and didn’t want to traverse a lot. So he wanted to visit each of these n cities at least once with smallest possible traverse. Persian cities are connected with bidirectional roads. You can go from any city to any other one using these roads and there is a unique path between each two cities.
All cities are numbered 1 to n. Shapur is currently in the city 1 and he wants to visit all other cities with minimum possible traverse. He can finish his travels in any city.
Help Shapur find how much He should travel.
Input
First line contains a single natural number n (1 ≤ n ≤ 105) — the amount of cities.
Next n - 1 lines contain 3 integer numbers each xi, yi and wi (1 ≤ xi, yi ≤ n, 0 ≤ wi ≤ 2 × 104). xi and yi are two ends of a road and wi is the length of that road.
Output
A single integer number, the minimal length of Shapur’s travel.
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).
Examples
input
3
1 2 3
2 3 4
output
7
input
3
1 2 3
1 3 3
output
9
题意:给定一个无向连通加权图,顶点数为n边数为n-1,从起点开始遍历图中每个顶点(结束点任意),问所花费最小权重。
思路:可以贪心找到规律,从起点出发,到达任意节点,除起点到终点的一条路径外,其余路径都经过过两次,所以可得结论:最小权重=所有边权之和*2-最大权重路径(从起点到终点),故可化简为求图中最长路的过程,利用深搜或者dij可解。
一下给出队列优化dij ac代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 6;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
ll dis[MAXN];
bool vis[MAXN];
int n;
ll x, y, w;
struct node
{
ll v, w;
bool operator < (const node& a)const
{
return this->w < a.w;
}
};
vector<node>ve[MAXN];
void Dijkstra(int s)
{
for (int i = 0; i <= n; i++)
dis[i] = 0;
priority_queue<node>que;
que.push({ s,0 });
dis[s] = 0;
while (!que.empty())
{
node tmp = que.top();
que.pop();
int u = tmp.v;
if (vis[u])continue;
vis[u] = true;
for (int i = 0; i < ve[u].size(); i++)
{
int v = ve[u][i].v;
int cost = ve[u][i].w;
if (!vis[v] && dis[v] < dis[u] + cost)
{
dis[v] = dis[u] + cost;
que.push({ v,dis[v] });
}
}
}
}
int main()
{
ll ans = 0, maxx = 0;
scanf("%d", &n);
for (int i = 0; i < n - 1; i++)
{
scanf("%lld%lld%lld", &x, &y, &w);
ve[x].push_back({ y,w });
ve[y].push_back({ x,w });
ans += w;
}
Dijkstra(1);
for (int i = 1; i <= n; i++)
if (dis[i] != inf)
{
maxx = max(maxx, dis[i]);
//printf("%lld\n", dis[i]);
}
printf("%lld\n", 2 * ans - maxx);
return 0;
}
dfs ac代码;
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 6;
struct edge{
ll v, w;
edge(ll v, ll w){ this->v = v; this->w = w; }
edge(){}
};
vector<edge>mp[MAXN];
ll n, ans, maxx;
bool vis[MAXN];
void dfs(ll now, ll maxn){
if (mp[now].size() == 0)return;
vis[now] = true;
for (auto it = mp[now].begin(); it != mp[now].end(); it++){
if (!vis[(*it).v])
dfs((*it).v, maxn + (*it).w);
}
maxx = max(maxx, maxn);
}
int main(){
scanf("%lld", &n);
for (int i = 1; i < n; i++){
ll u, v, w;
scanf("%lld %lld %lld", &u, &v, &w);
ans += w;
mp[u].push_back(edge(v, w));
mp[v].push_back(edge(u, w));
}
ll p = 0;
dfs(1, p);
ans = ans * 2 - maxx;
printf("%lld\n", ans);
return 0;
}