题目链接:Click here~~
题意:
有n+1个点,这n+1个点由n条边相连,且保证连通。然后给出各个点到出口的距离,要求从0点出发,遍历完n个点后立刻从出口出去。求最少时间。
解题思路:
由于n+1个点由n条边相连且连通,所以它肯定是一棵树,而且每个点到根节点的距离唯一。
从根节点出发遍历一棵树后,如果回到根节点,那么它一定走了2倍的树的边的权值之和。
所以我们可以把出发点0看做根节点,然后通过bfs求出各个点到根节点的距离step[i]。
然后我们就可以求出假设它遍历完后回到根节点的总距离sum,然后对于点i,它花费的实际值s=sum-step[i]+out[i],枚举找到最小的即可。
#include <queue>
#include <stdio.h>
#include <string.h>
#define N 100003
typedef __int64 LL;
using namespace std;
struct Point
{
int v,cost;
}R;
struct G
{
vector <Point> V;
}vv[N];
LL step[N],sum,ans;
queue <int> S;
int out[N];
void bfs()
{
int u,v;
S.push(0);
step[0] = 0;
while(!S.empty())
{
u = S.front();
S.pop();
while(!vv[u].V.empty())
{
R = vv[u].V.back();
vv[u].V.pop_back();
v = R.v;
if(step[v]!=-1)
continue;
step[v] = step[u] + R.cost;
S.push(v);
}
}
}
int main()
{
int n,a,b,c;
while(~scanf("%d",&n))
{
ans = sum = 0;
memset(step,-1,sizeof(step));
for(int i=0;i<=n;i++)
scanf("%d",&out[i]);
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
sum += c;
R.cost = c;
R.v = b;
vv[a].V.push_back(R);
R.v = a;
vv[b].V.push_back(R);
}
sum *= 2;
bfs();
for(int i=0;i<=n;i++)
{
LL s = sum - step[i] + out[i];
if(!ans || ans > s)
ans = s;
}
printf("%I64d\n",ans);
}
return 0;
}