zoukankan      html  css  js  c++  java
  • [JZOJ P1211] [dfs+图论]街道赛跑

    @kaike

    传送门

    话说回来,这也是很久之前的坑辣,我终于明白了oi的真谛,就是挖出一个又一个的坑,跳进去,然后再一个一个的填回去。

    输入十分坑,但是这是一个明显的坑点。

    n=-1;
    for(;;)
        {
            cin>>x;
            if(x==-1)   break;
            if(x==-2)   n++;
            else    e[n+1][x]=1;
        }

    这样就可以愉快地算出n值辣。

    第一问求什么“不可避免的路口”,也就是说少了那个点,图就不再联通。

    就是一层循环,枚举每一个点然后标记为1,起点0也标记为1,dfs(0);如果某个点图不再联通,加入到答案中,排序输出。

    第二问求“中间路口”,这不是一个求割点?

    好像不是吧....有向图,类似于割点却又不是割点的东西。

    用割点求过了两组,暴力!

     1 /*
     2 by kaike
     3 11/16/2016
     4 */
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<cstring>
     8 #include<string>
     9 #include<cstdio>
    10 using namespace std;
    11 const int MAXN=110;
    12 bool flag=0;
    13 int e[60][60],x,n=-1;
    14 int bok[60],ans[60],len=0;
    15 int num[60],low[60],root=0,index=0,summ=0;
    16 void dfs(int k)
    17 {
    18     if(k==n||flag==1)
    19     {
    20         flag=1;
    21         return ;
    22     }
    23     for(int i=0;i<=n;i++)
    24         if(bok[i]==0 && e[k][i] )
    25         {
    26             bok[i]=1;
    27             dfs(i);
    28             bok[i]=0;
    29         }
    30 }
    31 void init()
    32 {
    33     for(;;)
    34     {
    35         cin>>x;
    36         if(x==-1)   break;
    37         if(x==-2)   n++;
    38         else    e[n+1][x]=1;
    39     }
    40     for(int i=1;i<n;i++)
    41     {
    42         bok[i]=1;
    43         bok[0]=1;
    44         flag=0;
    45         dfs(0);
    46         bok[i]=0;
    47         if(flag==0)  ans[++len]=i;
    48     }
    49     sort(ans+1,ans+len+1);
    50     cout<<len<<' ';
    51     for(int i=1;i<=len;i++)
    52         cout<<ans[i]<<' ';
    53     cout<<endl;
    54 }
    55 void dfnlow(int cur,int father)
    56 {
    57     int child=0;
    58     index++;
    59     num[cur]=index;
    60     low[cur]=index;
    61     for(int i=0;i<=n;i++)
    62         if(e[cur][i])
    63         {
    64             if(num[i]==0)
    65             {
    66                 child++;
    67                 dfnlow(i,cur);
    68                 low[cur]=min(low[cur],low[i]);
    69                 if(cur!=root && low[i]>=num[cur])
    70                     bok[cur]=1;
    71                 if(cur==root &&child==2)
    72                     bok[cur]=1;
    73             }
    74             else if(i!=father)
    75                 low[cur]=min(low[cur],num[i]);
    76         }
    77 }
    78 void work()
    79 {
    80     for(int i=0;i<=n;i++)
    81         for(int j=0;j<=n;j++)
    82             if(e[i][j] &&i!=j)
    83                 e[j][i]=1;
    84     memset(bok,0,sizeof(bok));
    85     memset(ans,0,sizeof(ans));
    86     len=0;
    87     dfnlow(0,root);
    88 }
    89 int main()
    90 {
    91     init();
    92     work();
    93     for(int i=0;i<=n;i++)
    94         if(bok[i]==1)   cout<<i<<' ';
    95     return 0;
    96 }
    写了快100行结果过了两组 = = 十分不爽 

    正解是用两个ans数组,在第一次正向遍历的同时来一次反向遍历,标记出所能到达的路口,如果从起点出发经过的路口和从该路口出发经过的路口重合,说明这个路口不是中间路口。

    ---> 自从中间路口把图分成两部分,从中间路口出发和从起点出发之间经过的路口除中间路口肯定没有一样的 。  

    No matter how you feel, get up , dress up , show up ,and never give up.
  • 相关阅读:
    python+OpenCV 特征点检测
    如何使用《DB 查询分析器》高效地生成旬报货运量数据
    Hive-RCFile文件存储格式
    NET:交换机的背板带宽,交换容量,包转发率区别
    css:cdata
    [ZOJ 3623] Battle Ships
    [NYOJ 860] 又见01背包
    [Uva 11825] Hackers’ Crackdown
    2014-10-29
    [转] 三鲜之所在
  • 原文地址:https://www.cnblogs.com/Kaike/p/6070003.html
Copyright © 2011-2022 走看看