zoukankan      html  css  js  c++  java
  • POJ 1985.Cow Marathon-树的直径-树的直径模板(BFS、DFS(vector存图)、DFS(前向星存图))

    Time Limit: 2000MS   Memory Limit: 30000K
    Total Submissions: 7536   Accepted: 3559
    Case Time Limit: 1000MS

    Description

    After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has committed to create a bovine marathon for his cows to run. The marathon route will include a pair of farms and a path comprised of a sequence of roads between them. Since FJ wants the cows to get as much exercise as possible he wants to find the two farms on his map that are the farthest apart from each other (distance being measured in terms of total length of road on the path between the two farms). Help him determine the distances between this farthest pair of farms. 

    Input

    * Lines 1.....: Same input format as "Navigation Nightmare".

    Output

    * Line 1: An integer giving the distance between the farthest pair of farms. 

    Sample Input

    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    

    Sample Output

    52
    

    Hint

    The longest marathon runs from farm 2 via roads 4, 1, 6 and 3 to farm 5 and is of length 20+3+13+9+7=52. 
     
    题意就是求树的直径。水这篇博客为了存板子,自己创的板子,不知道写其他题怎么样,自我感觉很好用,因为自己用着顺手。
     
    代码1(BFS版):
      1 //BFS
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<bitset>
      7 #include<cassert>
      8 #include<cctype>
      9 #include<cmath>
     10 #include<cstdlib>
     11 #include<ctime>
     12 #include<deque>
     13 #include<iomanip>
     14 #include<list>
     15 #include<map>
     16 #include<queue>
     17 #include<set>
     18 #include<stack>
     19 #include<vector>
     20 using namespace std;
     21 typedef long long ll;
     22 typedef long double ld;
     23 typedef pair<int,int> pii;
     24 
     25 const double PI=acos(-1.0);
     26 const double eps=1e-6;
     27 const ll mod=1e9+7;
     28 const int inf=0x3f3f3f3f;
     29 const int maxn=1e5+10;
     30 const int maxm=100+10;
     31 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     32 
     33 int n,m,cnt;//cnt为边数
     34 int dist[maxn],head[maxn];//dist表示最长路,head为存图用的
     35 bool vis[maxn];
     36 
     37 struct node{//定义边的结构体
     38     int from,to,val,next;
     39 }edge[maxn<<1];//注意是无向图,边数是二倍的
     40 
     41 void init()//初始化,不可少
     42 {
     43     cnt=0;
     44     memset(head,-1,sizeof(head));
     45 }
     46 
     47 void addedge(int u,int v,int w)
     48 {
     49     edge[cnt].from=u;//起点
     50     edge[cnt].to=v;//终点
     51     edge[cnt].val=w;//权值
     52     edge[cnt].next=head[u];//指向下一条边
     53     head[u]=cnt++;
     54 }
     55 
     56 int length;//最终的最长路径(树的直径)
     57 int node;//记录端点值
     58 
     59 void bfs(int s)
     60 {
     61     queue<int>q;//定义队列
     62     memset(vis,false,sizeof(vis));//初始化,清零
     63     memset(dist,0,sizeof(dist));
     64     q.push(s);//入列
     65     vis[s]=true;//记录为遍历过的点
     66     length=0;
     67     node=s;
     68     while(!q.empty()){
     69         int u=q.front();
     70         q.pop();
     71         for(int i=head[u];i!=-1;i=edge[i].next){//遍历每一条边
     72             int v=edge[i].to;
     73             if(!vis[v]&&dist[v]<dist[u]+edge[i].val){
     74                 vis[v]=true;
     75                 dist[v]=dist[u]+edge[i].val;//到v的最长路径
     76                 if(length<dist[v]){
     77                     length=dist[v];//不断更新最长路径
     78                     node=v;//更新节点
     79                 }
     80                 q.push(v);//重新入列,寻找下一个点
     81             }
     82         }
     83     }
     84 }
     85 
     86 int main()
     87 {
     88     init();
     89     scanf("%d%d",&n,&m);
     90     for(int i=1;i<=m;i++){
     91         int u,v,val;char c[5];
     92         scanf("%d%d%d%s",&u,&v,&val,c);
     93         addedge(u,v,val);
     94         addedge(v,u,val);
     95     }
     96     bfs(1);//第一遍找到距离最远的端点
     97     bfs(node);//第二遍找最长距离
     98     printf("%d
    ",length);
     99     return 0;
    100 }
    View Code

    代码2(DFS vector存图版):

     1 //DFS-vector存图
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<bitset>
     7 #include<cassert>
     8 #include<cctype>
     9 #include<cmath>
    10 #include<cstdlib>
    11 #include<ctime>
    12 #include<deque>
    13 #include<iomanip>
    14 #include<list>
    15 #include<map>
    16 #include<queue>
    17 #include<set>
    18 #include<stack>
    19 #include<vector>
    20 using namespace std;
    21 typedef long long ll;
    22 typedef long double ld;
    23 typedef pair<int,int> pii;
    24 
    25 const double PI=acos(-1.0);
    26 const double eps=1e-6;
    27 const ll mod=1e9+7;
    28 const int inf=0x3f3f3f3f;
    29 const int maxn=1e5+10;
    30 const int maxm=100+10;
    31 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    32 
    33 struct node{
    34     int to,val;
    35 };
    36 
    37 int n,m,length,start;//length为路径长度,start为树的直径开始的节点
    38 vector <node> G[maxn<<1];//存图
    39 bool vis[maxn<<1];
    40 int dist[maxn<<1];
    41 
    42 void init()//初始化
    43 {
    44     length=-1;
    45     memset(vis,false,sizeof(vis));
    46     for(int i=0;i<n;i++)
    47         dist[i]=inf;
    48 }
    49 
    50 void dfs(int u)
    51 {
    52     vis[u]=true;
    53     for(int i=0;i<G[u].size();i++){//对与顶点u相连的点数进行扫描
    54         node v=G[u][i];
    55         if (!vis[v.to]){//如果没有访问过
    56             dist[v.to]=dist[u]+G[u][i].val;//更新节点
    57             if(dist[v.to]>length&&dist[v.to]!=inf){//更新路径长度
    58                 length=dist[v.to];
    59                 start=v.to;//更新节点
    60             }
    61             dfs(v.to);
    62         }
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     scanf("%d%d",&n,&m);
    69     for(int i=1;i<=m;i++){
    70         int u,v,w;char c[5];
    71         scanf("%d%d%d%s",&u,&v,&w,c);
    72         G[u-1].push_back({v-1,w});
    73         G[v-1].push_back({u-1,w});
    74     }
    75     init();dist[0]=0;dfs(0);
    76     init();dist[start]=0;dfs(start);
    77     printf("%d
    ",length);
    78 }
    View Code

    代码3(DFS 前向星存图版):

     1 //DFS-前向星存图
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<bitset>
     7 #include<cassert>
     8 #include<cctype>
     9 #include<cmath>
    10 #include<cstdlib>
    11 #include<ctime>
    12 #include<deque>
    13 #include<iomanip>
    14 #include<list>
    15 #include<map>
    16 #include<queue>
    17 #include<set>
    18 #include<stack>
    19 #include<vector>
    20 using namespace std;
    21 typedef long long ll;
    22 typedef long double ld;
    23 typedef pair<int,int> pii;
    24 
    25 const double PI=acos(-1.0);
    26 const double eps=1e-6;
    27 const ll mod=1e9+7;
    28 const int inf=0x3f3f3f3f;
    29 const int maxn=1e5+10;
    30 const int maxm=100+10;
    31 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    32 
    33 struct node{
    34     int to,nex,val;
    35 }edge[maxn<<1];
    36 
    37 int n,m,cnt=0,length,start;
    38 int dist[maxn<<1],head[maxn<<1];
    39 bool vis[maxn];
    40 
    41 void addedge(int x,int y,int w)
    42 {
    43     edge[++cnt].to=y;
    44     edge[cnt].val=w;
    45     edge[cnt].nex=head[x];
    46     head[x]=cnt;
    47 }
    48 
    49 void init()//初始化
    50 {
    51     length=-1;
    52     memset(vis,false,sizeof(vis));
    53     for(int i=0;i<n;i++)
    54         dist[i]=inf;
    55 }
    56 
    57 void dfs(int u)
    58 {
    59     vis[u]=true;
    60     for(int i=head[u];i;i=edge[i].nex){//对与顶点u相连的点数进行扫描
    61         int v=edge[i].to;
    62         if (!vis[v]){//如果没有访问过
    63             dist[v]=dist[u]+edge[i].val;//更新节点
    64             if(dist[v]>length&&dist[v]!=inf){//更新路径长度
    65                 length=dist[v];
    66                 start=v;//更新节点
    67             }
    68             dfs(v);
    69         }
    70     }
    71 }
    72 
    73 int main()
    74 {
    75     scanf("%d%d",&n,&m);
    76     for(int i=1;i<=m;i++){
    77         int u,v,w;char c[5];
    78         scanf("%d%d%d%s",&u,&v,&w,c);
    79         addedge(u-1,v-1,w);
    80         addedge(v-1,u-1,w);
    81     }
    82     init();dist[0]=0;dfs(0);
    83     init();dist[start]=0;dfs(start);
    84     printf("%d
    ",length);
    85 }
    View Code

    OK,滚了。。。

     
  • 相关阅读:
    电工知识:3种方法测电容的好坏,万用表三个档位的巧妙应用
    ps 教程
    绘声绘影 设置不联网
    推荐.Net、C# 逆向反编译四大工具利器
    MOOC 网站:Coursera、Udacity、edX
    深度强化学习资料(视频+PPT+PDF下载)
    李飞飞、吴恩达、Bengio等人的15大顶级深度学习课程
    tf.name_scope()和tf.variable_scope()
    Linux 进程(一):环境及其控制
    Linux I/O总结
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10444886.html
Copyright © 2011-2022 走看看