zoukankan      html  css  js  c++  java
  • 【搜索】codeforces C. The Tag Game

    http://codeforces.com/contest/813/problem/C

    【题意】

    给定一棵有n个结点的树,初始时Alice在根结点1,Bob在非根结点x;

    Alice和Bob轮流走,每一步都有两种选择:走向相邻结点或静止不动,Bob先走;

    当Alice和Bob相遇时游戏结束;

    Alice的目标是游戏结束是的总步数最少,Bob的目标是游戏结束时总步数最少;

    求最后的总步数是多少。

    2 ≤ n ≤ 2·10^5, 2 ≤ x ≤ n

    【思路】

    Alice想要游戏尽早结束,所以Alice的每一步是靠近Bob; Bob不想游戏结束,所以他选择躲Alice,在尽量不遇到Alice的情况下选择一条最长的路径然后逃到这条路的叶节点不动。所以可以这样做:

    bfs求出树上每个点k到1的距离dis[k],O(n)
    bfs求出树上每个点k到x的距离dist[k],O(n)

    如果dis[k]<dist[k],说明k是可行点,在所有可行点中找到最大的dist[k]。

    还有一种方法更复杂一点:

    找出x到1的路径上的可行点k,所谓可行点就是当Bob到达这点的时候Alice还没有到达,1->k的路径长度+以结点K为根的子树高度

    dfs一次找出每个点的深度和高度,O(n)

    dfs一次找出1->x路径上的结点,O(n)

    【Accepted】

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <cmath>
      4 #include <vector>
      5 #include <algorithm>
      6 #include <set>
      7 #include <map>
      8 #include <queue>
      9 #include <deque>
     10 #include <stack>
     11 #include <string>
     12 #include <bitset>
     13 #include <ctime>
     14 #include<algorithm>
     15 #include<cstring>
     16 using namespace std;
     17 typedef long long ll;
     18 const int maxn=2e5+3;
     19 const int inf=0x3f3f3f3f;
     20 int n,x; 
     21 struct node
     22 {
     23     int to;
     24     int nxt;
     25 }edge[maxn<<1];
     26 int tot;
     27 int ans;
     28 int head[maxn];
     29 int du[maxn];
     30 int dis[maxn];
     31 int dist[maxn];
     32 void Init()
     33 {
     34     memset(head,-1,sizeof(head));
     35     memset(dis,inf,sizeof(dis));
     36     memset(dist,inf,sizeof(dist));
     37     tot=0;
     38     ans=0;
     39 }
     40 void add(int u,int v)
     41 {
     42     edge[tot].to=v;
     43     edge[tot].nxt=head[u];
     44     head[u]=tot++;
     45 }
     46 void bfs1(int u)
     47 {
     48     int vis[maxn];
     49     memset(vis,0,sizeof(vis));
     50     dist[u]=0;
     51     vis[u]=1;
     52     queue<int> Q;
     53     Q.push(u);
     54     while(!Q.empty())
     55     {
     56         u=Q.front();
     57         Q.pop();
     58         for(int i=head[u];i!=-1;i=edge[i].nxt)
     59         {
     60             int to=edge[i].to;
     61             if(vis[to])
     62             {
     63                 continue;
     64             }
     65             dist[to]=dist[u]+1;
     66             vis[to]=1;
     67             Q.push(to);
     68         }
     69     }
     70 }
     71 
     72 void bfs2(int u)
     73 {
     74     int vis[maxn];
     75     memset(vis,0,sizeof(vis));
     76     dis[u]=0;
     77     vis[u]=1;
     78     queue<int> Q;
     79     Q.push(u);
     80     while(!Q.empty())
     81     {
     82         u=Q.front();
     83         Q.pop();
     84         for(int i=head[u];i!=-1;i=edge[i].nxt)
     85         {
     86             int to=edge[i].to;
     87             if(vis[to])
     88             {
     89                 continue;
     90             }
     91             dis[to]=dis[u]+1;
     92             vis[to]=1;
     93             Q.push(to);
     94         }
     95     }
     96 }
     97 
     98 void Solve()
     99 {
    100     bfs1(1);
    101     bfs2(x);
    102     for(int i=1;i<=n;i++)
    103     {
    104     //    cout<<dis[i]<<" "<<dist[i]<<endl;
    105         if(dis[i]<dist[i])
    106         {
    107             ans=max(ans,dist[i]);    
    108         }    
    109     }
    110     cout<<ans*2<<endl;
    111 }
    112 int main()
    113 {
    114     while(~scanf("%d%d",&n,&x))
    115     {
    116         Init();
    117         int u,v;
    118         for(int i=0;i<n-1;i++)
    119         {
    120             scanf("%d%d",&u,&v);
    121             add(u,v);
    122             add(v,u);
    123             du[u]++;
    124             du[v]++;
    125         }
    126         Solve();
    127     }
    128     return 0;
    129 }
    BFS
      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <cmath>
      4 #include <vector>
      5 #include <algorithm>
      6 #include <set>
      7 #include <map>
      8 #include <queue>
      9 #include <deque>
     10 #include <stack>
     11 #include <string>
     12 #include <bitset>
     13 #include <ctime>
     14 #include<algorithm>
     15 #include<cstring>
     16 using namespace std;
     17 typedef long long ll;
     18 
     19 int n,x;
     20 const int maxn=2e5+3;
     21 struct node
     22 {
     23     int to;
     24     int nxt;
     25 }edge[maxn<<1];
     26 int tot;
     27 int head[maxn];
     28 int du[maxn];
     29 int dep[maxn];
     30 int path[maxn];
     31 int vis[maxn];
     32 int d[maxn];
     33 int col;
     34 int ans;
     35 void Init()
     36 {
     37     memset(path,0,sizeof(path));
     38     memset(du,0,sizeof(du));
     39     memset(head,-1,sizeof(head));
     40     memset(dep,0,sizeof(dep));
     41     memset(vis,0,sizeof(vis));
     42     memset(d,0,sizeof(d));
     43     tot=0;
     44     col=0;
     45     ans=0;
     46 }
     47 void add(int u,int v)
     48 {
     49     edge[tot].to=v;
     50     edge[tot].nxt=head[u];
     51     head[u]=tot++;
     52 }
     53 
     54 int dfs(int u,int pre)
     55 {
     56     for(int i=head[u];i!=-1;i=edge[i].nxt)
     57     {
     58         int to=edge[i].to;
     59         if(to==pre)
     60         {
     61             continue;
     62         }
     63         dep[to]=dep[u]+1;
     64         d[u]=max(d[u],dfs(to,u)+1);
     65     }
     66     return d[u];
     67 }
     68 
     69 void pdfs(int u,int pre,int cnt)
     70 {
     71     if(col!=0)
     72     {
     73         return;
     74     }
     75     path[cnt]=u;
     76     if(u==x)
     77     {
     78         col=cnt;
     79         return;
     80     }
     81     for(int i=head[u];i!=-1;i=edge[i].nxt)
     82     {
     83         int to=edge[i].to;
     84         if(to==pre)
     85         {
     86             continue;
     87         }
     88         pdfs(to,u,cnt+1);
     89     }
     90 }
     91 void Solve()
     92 {
     93     dfs(1,0);
     94     pdfs(1,0,1);
     95     vis[1]=1;
     96     for(int i=col,k=2;i>=1,k<=col;i--,k++)
     97     {
     98         if(!vis[i])
     99         {
    100             ans=max(ans,d[path[i]]+dep[path[i]]);
    101         }
    102         vis[k]=1;
    103     }
    104     cout<<ans*2<<endl;
    105     
    106 }
    107 int main()
    108 {
    109     while(~scanf("%d%d",&n,&x))
    110     {
    111         Init();
    112         int u,v;
    113         for(int i=0;i<n-1;i++)
    114         {
    115             scanf("%d%d",&u,&v);
    116             add(u,v);
    117             add(v,u);
    118             du[u]++;
    119             du[v]++;
    120         }
    121         Solve();
    122     }
    123     return 0;
    124 }
    DFS
  • 相关阅读:
    题解 CF577B 【Modulo Sum】
    题解 P2827 【蚯蚓】
    题解 P1219 【八皇后】
    flash小实验
    URL编解码
    速记:两个进程模拟模态窗口
    youtube weburl后缀
    给ListView的条目自绘边框
    flash全屏在Activex控件上和在Google chrome插件上的区别
    ListView的消息钩子
  • 原文地址:https://www.cnblogs.com/itcsl/p/6953781.html
Copyright © 2011-2022 走看看