学会思考技术背后的那些思想和本质

题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量。

思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可。算法相对简单,但是注意几个细节:

1:原图可能不连通。

2:有的连通分量只有一个点,当舍去该点时候,连通分量-1;

复习求割点的好题!

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int n,m;
vector<vector<int> >e(10010);
int dfn[5010];int low[5010];int vis[5010];
int times=0;
int subset[5010];
int root=0;
int rf=0;
int son=0;
void tarjan(int u,int fa)     //无向图tarjan记录父亲
{
    if(u==rf)return;          //是被枚举的点,舍去(从图中删去)。
    dfn[u]=low[u]=times++;
    for(int i=0;i<e[u].size();i++)
    {
        int v=e[u][i];
        if(v==rf)continue;     // 这里注意,舍去的点不要了
        if(!vis[v])
        {
            vis[v]=1;
            tarjan(v,u);
            if(low[v]<low[u])low[u]=low[v];
            if(u==root)                   //求割点是根的情况
              {
                  son++;
              }
            else                  // 其他情况
            {
                if(dfn[u]<=low[v])    //subset【u】+1记录 以u为割点后形成的连通分量数
                    subset[u]++;
            }

        }
        else if(v!=fa)         //条件注意
        {
            if(dfn[v]<low[u])low[u]=dfn[v];
        }
    }
    return ;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<=n;i++)
           {
             dfn[i]=low[i]=subset[i]=vis[i]=0;
             e[i].clear();
           }
        int ta,tb;
      for(int i=0;i<m;i++)
      {
          scanf("%d%d",&ta,&tb);
           e[ta].push_back(tb);
           e[tb].push_back(ta);
      }
      int maxx=0;
      for(int i=0;i<n;i++)   //枚举每个点
      {
          rf=i;               //i舍去
          vis[rf]=1;
          int scc=0;
          int maxson=0;
          for(int iii=0;iii<n;iii++)          //考虑原图不连通!
             {
                 if(!vis[iii])
                 {
                     vis[iii]=1;
                     root=iii;
                     tarjan(iii,-1);
                     scc++;                     //连通分量数
                     if(son>maxson)maxson=son;    //求出每个连通分量的根的最大的son
                     son=0;                         //每个连通分量要更新son
                 }
             }
            if(e[i].size()==0)scc--;    // 注意点!!!:该连通分量只有一个点!舍去的话就没了。
          for(int ii=0;ii<n;ii++)             //取最大的
          {
              if(scc+subset[ii]+1-1>maxx)maxx=scc+subset[ii]+1-1;
          }
          if(scc+maxson-1>maxx)maxx=maxson+scc-1;
          for(int j=0;j<n;j++)    //不忘更新!
          {
              dfn[j]=low[j]=subset[j]=vis[j]=0;
          }
          son=times=0;
      }
      cout<<maxx<<endl;
    }
    return 0;
}

学会思考技术背后的那些思想和本质

时间: 2024-10-05 04:29:37

学会思考技术背后的那些思想和本质的相关文章

不要学习代码,要学会思考(转)

英文原文:Don't learn to code, learn to think 译/赖信涛 这是一个人人都在学习编程的时代:Code.org请了比尔·盖茨,马克·扎克伯格和克里斯·波什等这些名人,来告诉你,每个人都可以编程:CoderDojo’s在各个国家悄然兴起:在英国,编程已经是各个年级学生的正式课程. 我认为这里有个误区.别误会我——如果每个人都会一些编程知识,这个世界当然会变得更好——但是学会写代码不应该是我们的目标.计算机和程序只是一个工具,是一种达到某种目的的方法. 真正的目标应该

不仅学习代码,也要学会思考

这是一个人人都在学习编程的时代: [合肥开源IT教育][开源培训][php培训][开源教育][开源IT教育培训][合肥php培训]Code.org请了比尔·盖茨,马克·扎克伯格和克里斯·波什等这些名人,来告诉你,每个人都可以编程:CoderDojo’s在各个国家悄然兴起:在英国,编程已经是各个年级学生的正式课程.我认为这里有个误区.别误会我——如果每个人都会一些编程知识,这个世界当然会变得更好——但是学会写代码不应该是我们的目标.计算机和程序只是一个工具,是一种达到某种目的的方法.真正的目标应该

不要学习代码,要学会思考《IT蓝豹》

这是一个人人都在学习编程的时代:Code.org请了比尔·盖茨,马克·扎克伯格和克里斯·波什等这些名人,来告诉你,每个人都可以编程:CoderDojo's在各个国家悄然兴起:在英国,编 程已经是各个年级学生的正式课程. 我认为这里有个误区.别误会我--如果每个人都会一些编程知识,这个世界当然会变得更好--但是学会写代码不应该是我们的目标.计算机和程序只是一个工具,是一种达到某种目的的 方法. 真正的目标应该是学会思考的方式.换句话说,我们应该尝试教授计算机科学,而不是教着写代码.在本文中,我将介

不要只为学习代码,要学会思考

这是一个人人都在学习编程的时代:Code.org请了比尔·盖茨,马克·扎克伯格和克里斯·波什等这些名人,来告诉你,每个人都可以编程:CoderDojo's在各个国家悄然兴起:在英国,编程已经是各个年级学生的正式课程. 我认为这里有个误区.别误会我--如果每个人都会一些编程知识,这个世界当然会变得更好--但是学会写代码不应该是我们的目标.计算机和程序只是一个工具,是一种达到某种目的的方法. 真正的目标应该是学会思考的方式.换句话说,我们应该尝试教授计算机科学,而不是教着写代码.在本文中,我将介绍两

思考技术之源

技术: 实现预定目的的具体可执行的方法.步骤.流程.工具等的聚合. 技术之源: 思想在不同场景和环境下的变通.实践和实现. 云计算:资源和服务的集中化.虚拟化管理在IT基础设施建设上的体现: 大数据:试图从统计学角度通过海量数据分析来揭示自然和社会的心理.行为和活动的规律,从而更好地预测和决策. HTML5,模板引擎,语言与编译器: “标记-解释器”思想在前端开发中的应用.html/js/css 本质上是一套完善的标记系统,而浏览器是其解释者.标记系统可以从语义上更加智能化. web框架: 关注

学会思考 善于思考

思考并非难事,却止于惰性,在此鼓励自己学会思考.善于思考.乐于思考.韦玉smile,加油! 注册这个平台冥冥之中还要感谢一位博友,缘于偶然查找资料时,发现他的随笔,不讲究却很实用,真实地记录着他的学习和思考.有种冲动告诉我,为自己创造一个这样的平台吧,对工作生活有什么想法就写下来,过些日子自己能看懂,过几年还知道自己曾经想过,如此而已,就挺好!

怎样快速学会一门技术(转载)

前几天 fork 了 Ruby China 的源码,面对陌生的 Ruby 技术栈,一头雾水. 我 fork 它并不单为了学习,而是要在最短的时间搭建起我脑海中的社区网站.所以我不可能针对每一门新技术都去买一本书来读上半个月. 我在本机运行起 Ruby China,新注册一个用户,发现不能发帖,提示说要注册一个月以上才可以.于是我去找相关代码: # 是否能发帖 def newbie? return false if self.verified == true self.created_at > 1

学会思考

世界上没有解决不了的问题,任何事情都必须有解决方案.只是解决方案有好的和不好的,所以为了让自己在遇到任何问题之时能尽可能提炼出好的解决方案,就必须学会掌握解决所有问题的方法,也就是学会思考--逻辑思考能力 1.目的 做任何事情,处理任何问题,在行动之前,首先明确自己的目标是什么 2.优势 对待一件事情时,先观大局,分析在处理此事时,自己有哪些优势 3.劣势 分析完优势,当然接下来就是要找出自己可能存在的问题,那就是劣势,这样才能扬长避短 4.方法 所谓方法,就是在处理一件事情的过程所采用的处理流

学会思考--菜鸟程序员晋升大神之路

"菜鸟"和"大神" 刚刚走出就业的程序员,技术是刚刚起步的基点.那下面我们就聊一聊有关技术的东西.首先请您先想想这几个问题.现在社会上有很多程序员,那您是否可想过程序 员为什么会有不同的水平?你又是哪一类的程序员?"菜鸟"程序员和"大神"程序员差在哪里?真是差在技术上了吗?那不是差在技术上那差在了哪里? 上面很多一连串的问题,没有把你搞晕吧!那就听我一一给您分析这个问题背后的答案.确切的说程序员分为"菜鸟"