大臣的旅费(2次dfs)

来源:互联网 发布:mac mini 安装 win10 编辑:程序博客网 时间:2024/05/22 16:50

问题描述
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。

为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。

J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。

聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。

J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?

输入格式
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数

城市从1开始依次编号,1号城市为首都。

接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)

每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。

输出格式
输出一个整数,表示大臣J最多花费的路费是多少。

样例输入1
5
1 2 2
1 3 1
2 4 5
2 5 4
样例输出1
135
输出格式
大臣J从城市4到城市5要花费135的路费。

题意:
就是求图的最长路径,這里的图就是树。方法就是2次DFS,第一次任意选择一个顶点开始DFS,得到最长路径对应的点。再从此点第二次DFS,即可得到最长路径d。
至于为啥呢,就不知道了,数学也不是很好,推不出来。
最后的旅费就是一个公式
费用=10*d+(d+1)**d/2;
有一点需要注意的是不能用邻接矩阵,最后一个测试数据有10000个结点,用邻接矩阵的话就是10000*10000,没有这么大的连续空间。做法就是用邻接表来存储,DFS基本还是不变。
下面附上我的代码(有点粗糙-_-):

#include <iostream>#include <vector>using namespace std;struct Edge{    int adjV,cost;};int maxLength = 0;vector<Edge> G[100010];vector<bool> visited;int v,dis;void dfs(int sum,int pos,int n)     {    if (sum > dis)    {        dis = sum;        v = pos;    }    visited[pos] = true;    for (int i = 0; i < G[pos].size(); i++)    {        Edge p = G[pos][i];        if(!visited[p.adjV])        {            sum += p.cost;            dfs(sum,p.adjV, dis);            visited[p.adjV] = false;            sum -= p.cost;        }    }}int main(){    int n;    cin >> n;    int p, q, d;    visited.resize(n + 1);    fill(visited.begin(), visited.end(), false);    Edge node;    for (int i = 0; i < n-1; i++)    {        cin >> p >> q >> d;        node.adjV = q;        node.cost = d;        G[p].push_back(node);        node.adjV = p;        G[q].push_back(node);    }    dfs(0,1,n);             //第一遍深搜从1点开始,寻找最长路径对应的点v    fill(visited.begin(), visited.end(), false);    dis = 0;    dfs(0, v, n);    cout << 10 * dis + dis*(dis + 1) / 2 << endl;    return 0;}

下面的代码是老师写的,老师不屑于用全局变量(惭愧倒下,我用的全是全局)
个人觉得没有问题,可就是AC不了,不知道为啥,也附上把。

#include <iostream>#include <fstream>#include <vector>using namespace std;struct Edge{int adjv; //邻接点下标:从0数起int cost;};struct Node{vector<Edge> adjlist;};struct VDist{int v;    // 终点下标int dist; // 到达终点的距离};VDist dfs(vector<Node> &G, int v);VDist dfs(vector<Node> &G,int visited[], int v,VDist vd);int main(){//ifstream fin("input.txt");int i,n; cin>>n;vector<Node> G;for( i=0; i<n; i++){Node n; G.push_back(n);}for(i=0; i<n-1; i++){int si,ei,cost;cin>>si>>ei>>cost;  si--; ei--;Edge e1={ei,cost};G[si].adjlist.push_back(e1);Edge e2={si,cost};G[ei].adjlist.push_back(e2);}VDist sv=dfs(G,0);VDist ev=dfs(G, sv.v);//cout<<sv.v<<"->" <<ev.v<<": "<<ev.dist<<endl;int d=ev.dist;cout<<10*d+(d+1)*d/2;return 1;}VDist dfs(vector<Node> &G, int v){int n=G.size();int *visited=new int[n];for(int i=0; i<n; i++)  visited[i]=0;VDist vd={0, 0};  // 初始解VDist maxvd=dfs(G,visited,v,vd);return maxvd;}VDist dfs(vector<Node> &G,int visited[], int v, VDist vd){VDist maxvd=vd;visited[v]=1;for(int i=0; i<G[v].adjlist.size(); i++){int w=G[v].adjlist[i].adjv;if(visited[w]==0){VDist vdw ={w, vd.dist+G[v].adjlist[i].cost};vdw = dfs(G,visited,w, vdw);if(vdw.dist > maxvd.dist)maxvd = vdw;}}return maxvd;}
0 0