POJ 1849 Two (树的直径)

题目链接

题意:一棵树。。然后初始两个推雪机在点s,问如何选择路径使得处理完所有边上的积雪所耗费的汽油最少(走过一条有雪的边和一条没雪的边耗费的汽油一样)

思路:很容易想到,我们应该尽可能不走已经被清理过雪了的边,因为这样很浪费。。。这样不难想到应该是和树的直径有关。但是初始的位置是给定的。。。怎么办?突然发现由于是给了两个推雪机。。所以其实相当于。。。只有一个推雪机&我们可以从任意位置开始推雪。。。第二个问题是。。。对于不在直径上的边。。我们怎么算cost?解决办法是读边的时候进行记录。。。然后求直径的时候记录路径。。。对于一条边。。。只要有一个点不在直径上。。。那么这条边的代价就是2倍。。。

1A蛤蛤蛤

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年07月17日 星期日 19时04分49秒
  4File Name :code/poj/1849.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=1E5+7;
 34vector < pi > edge[N];
 35int n,s;
 36int lst;
 37int beg;
 38int d[N];
 39bool vis[N];
 40bool onpath[N];
 41int path[N];
 42int ans;
 43
 44struct  Edge
 45{
 46    int u,v,w;
 47
 48}e[N];
 49void init( int n)
 50{
 51    for ( int i = 1 ; i <= n ; i++) edge[i].clear();
 52    ms(path,-1);
 53    ms(onpath,false);
 54}
 55
 56void bfs( int s)
 57{
 58    ms(d,0);
 59    ms(vis,false);
 60    queue<int>q;
 61    q.push(s);
 62    vis[s] = true;
 63
 64    while (!q.empty())
 65    {
 66	int u = q.front();
 67	q.pop();
 68
 69	int siz = edge[u].size();
 70
 71	for ( int i = 0 ;i  < siz;  i++)
 72	{
 73	    int v = edge[u][i].fst;
 74	    int w = edge[u][i].sec;
 75	    if (vis[v]) continue;
 76	    path[v] =  u;
 77	    vis[v] = true;
 78	    d[v] = d[u] + w;
 79	    q.push(v);
 80	}
 81    }
 82
 83}
 84int main()
 85{
 86	#ifndef  ONLINE_JUDGE 
 87	freopen("code/in.txt","r",stdin);
 88  #endif
 89
 90
 91	cin>>n>>s;
 92	init(n);
 93	for ( int i = 1  ;i <= n-1 ; i ++)
 94	{
 95	    int u,v,w;
 96	    scanf("%d%d%d",&u,&v,&w);
 97	    e[i].u = u;
 98	    e[i].v = v;
 99	    e[i].w = w;
100	    edge[u].push_back(make_pair(v,w));
101	    edge[v].push_back(make_pair(u,w));
102	}
103
104	bfs(1);
105	int mx = 0 ;
106	for ( int i = 1 ; i <= n ; i ++)
107	    if (d[i]>mx)
108	    {
109		mx = d[i];
110		lst = i;
111	    }
112
113	mx = 0 ;
114	ms(path,-1);
115	bfs(lst);
116
117	for ( int i = 1 ; i <= n ; i++)
118	    if (d[i]>mx)
119	    {
120		mx = d[i];
121		beg = i ;
122	    }
123
124	ans = mx;
125	int x = beg;
126	//cout<<"bfs ok?"<<endl;
127	while (x!=-1)
128	{
129	    //cout<<"x:"<<x<<endl;
130	    onpath[x] = true;
131	    x = path[x];
132	}
133
134//	cout<<"ans:"<<ans<<endl;
135	for ( int i = 1 ; i <= n-1 ; i++)
136	{
137	    int u = e[i].u;
138	    int v = e[i].v;
139	    int w = e[i].w;
140	    if (onpath[u]&&onpath[v]) continue;
141	    ans +=w*2;
142	}
143
144	printf("%d\n",ans);
145
146
147
148  #ifndef ONLINE_JUDGE  
149  fclose(stdin);
150  #endif
151    return 0;
152}