• 集训模拟赛-1-T1


    最近学校网课跟得紧没时间写知识点,就拿题解凑个数(bushi

    而且前两天我打着打着题解电脑就突然死机 幸运的是 我没有保存(微笑)

    废话不多说 上题目!

    城市攻击
    (city)
    (256MB,1s)
    【问题描述】
    出于某些原因,A国将对B国进行攻击。B国有n个城市,有n-1
    双向条道路,每条道路连接两个城市,任意两个城市可以通过道路
    互相到达,即构成一棵树。由于资金有限,A国只能攻击B国的两个
    城市,攻击后这两个城市将会毁灭,与这两个城市连接的道路也随
    之消失,A国希望在攻击后能将B国分成尽可能多的连通块,这样有
    利于A国的下一步行动,于是他们找到你来完成这个任务。
    【输入格式】
    输入文件名为city.in
    第一行包含一个整数T,表示数据组数。
    对于每组数据
    第一行包含一个整数n,表示B国城市的数量。
    接下来n-1行,每行两个整数x,y,表示有一条道路连接城市x与城市y
    【输出格式】
    输出文件名为city.out
    输出文件包含T个整数,表示对于每组数据,攻击两个城市后最多能
    使B国分成多少个连通块
    【输入样例】
    city.in city.out
    2
    5
    1 2
    2 4
    3 4
    4 5
    7
    1 2
    2 3
    1 4
    1 5
    3 6
    3 7
    3
    5

    【数据规模与约定】
    对于20%的数据T<=5,1≤n≤100
    对于50%的数据T<=5,1≤n≤1000
    对于100%的数据T<=10,1≤n≤100000

    看到这个题说实话我考试的时候二话不说直接爆搜= =

    但后来老师一讲就发现其实有窍门

    具体看我的详(la)细(ji)题解:

     1 //通过画图可以看出我们要通过删除度数最多的城市点来拆分连通块,在枚举过程中发现删除xy会得到d[x]+d[y]-n个连通块
     2 //且两点相连时n为2两点不连时n为1
     3 //max分别列举情况 判断即可 
     4 #include<cstdio>
     5 #include<cstdlib>
     6 #include<cstring>
     7 #include<iostream>
     8 using namespace std;
     9 struct node// 
    10 {
    11     int y,next;//y代表目标位, next的意义参照day3-例1 
    12 }a[2000010];
    13 int first[1000010],len;// first【x】从x出发的第一条边 
    14 int d[1000010];//度数 
    15 void ins(int x,int y)//边列表 
    16 {
    17     a[++len].y=y;
    18     a[len].next=first[x];
    19     first[x]=len;
    20 }
    21 bool is_conected(int x,int y)//判断两点之间有没有联系 
    22 {
    23     int k;
    24     for(k=first[x];k;k=a[k].next)
    25       if(a[k].y==y)return 1;
    26     return 0;
    27 }
    28 int main()
    29 {
    30     freopen("city.in","r",stdin);
    31     freopen("city.out","w",stdout);
    32     int o,n,i,j,k,x,y;
    33     scanf("%d",&o);//数据组数 
    34     while(o--)
    35     {
    36       scanf("%d",&n);//B国城市数量 
    37       for(i=1;i<=n;i++) first[i]=d[i]=0;//先全部清空一遍 
    38       len=0;//清空 
    39       for(i=1;i<n;i++)
    40       {
    41         scanf("%d%d",&x,&y);
    42         ins(x,y);ins(y,x);//存储他们的边 因为是无向图 所以当做双向用 
    43         d[x]++;d[y]++;//x,y的度数分别加1 
    44       }
    45       int max_d=0,sec_d=0;//max代指目前度数最大的点 sec代指度数第二大的点 _d代指这个度数的值 
    46       int max_s=0,m1,m2;//max_s代表目前最大点的个数 m1记录第一个最大点的编号 m2代表第二个 当这两个点都有存储时代表有两个及以上,如果最大度数的点有三个及以上不用记录 一定有两个最大度数点不相连
    47       int sec_s=0;//第二大度数的点的个数 
    48       for(i=1;i<=n;i++)//记录最大度数的点的个数以及第二大度数的点的个数 
    49       {
    50         if(d[i]>max_d)//扫描到的点的度数如果比当前的最大的度数值要大 
    51         {
    52           sec_d=max_d;
    53           sec_s=max_s;//当前的“最大”度数变成第二大,更新第二大的度数点的相关数据 
    54           max_d=d[i];
    55           max_s=1;m1=i;//更新最大度数点 m1更新 
    56         }
    57         else if(d[i]==max_d)
    58         {
    59           max_s++;//最大度数的点的个数+1 
    60           if(max_s==2)m2=i;//m2更新 
    61         }
    62         else if(d[i]>sec_d)//更新第二大的度数代表的一系列数据 
    63           sec_d=d[i],sec_s=1;
    64         else if(d[i]==sec_d)
    65           sec_s++;
    66       }//如果又else 什么都不用做 
    67       
    68       if(max_s>=3){printf("%d
    ",2*max_d-1);continue;} 
    69       if(max_s==2)
    70       {
    71         if(is_conected(m1,m2))//判断两点是否相连 
    72         printf("%d
    ",2*max_d-2);
    73         else printf("%d
    ",2*max_d-1);
    74         continue;
    75       }
    76       //max_s=1;无需判断,直接操作 
    77       int s=0;
    78       for(k=first[m1];k;k=a[k].next)//扫描从x出发的第一条边开始 意为消除第一个城市然后确定连通块数量 
    79       {
    80         y=a[k].y;
    81         if(d[y]==sec_d) s++;//这两步的意思是寻找与x相连的sec,s为计数点 
    82       }
    83       if(s==sec_s)//如果与max连接的点的数量与总的点的数量一样 
    84       printf("%d
    ",max_d+sec_d-2);//出推论 
    85       else printf("%d
    ",max_d+sec_d-1);//反之,出推论 
    86     }
    87     return 0;
    88 }

    好了大概就这么多

    但是这个题没A,why?

    因为!

    我不会离散化(哭了)

    好了如果你喜欢这篇题解别忘了点赞投币收藏……

    诶?好像跑题了= =

  • 相关阅读:
    springmvc结合freemarker,非自定义标签
    springmvc的ModelAndView的简单使用
    tomcat无法正常启动的一个原因
    通过springmvc的RequestMapping的headers属性的使用
    springmvc入门demo
    Redis的入门Demo(java)
    Ubuntu18.0.4查看显示器型号
    APS审核经验+审核资料汇总——计算机科学与技术专业上海德语审核
    Java连接GBase并封装增删改查
    SpringMVC源码阅读:异常解析器
  • 原文地址:https://www.cnblogs.com/SKTskyking/p/12292981.html
Copyright © 2020-2023  润新知