• HDU 4496 D-City



    1
    #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #define MAXN 10001 5 using namespace std; 6 int uset[MAXN]; 7 int Find(int x){return uset[x]==x?x:uset[x]=Find(uset[x]);} 8 int makeSet(int x,int y){ 9 int fx=Find(x),fy=Find(y); 10 if(fx!=fy){ 11 uset[fy]=fx; 12 return 1; 13 } 14 return 0; 15 } 16 int main() 17 { 18 int x,y,num,line; 19 while(scanf("%d%d",&num,&line)==2){ 20 for(int i=0;i<num;i++) uset[i]=i;// 21 22 int cnt=num; 23 vector<pair<int,int> > v; 24 while(line--){ 25 scanf("%d%d",&x,&y); 26 v.push_back(make_pair(x,y)); 27 } 28 29 vector<int> res;//store the result 30 res.push_back(cnt); 31 for(int i=v.size()-1;i>=1;i--) 32 cnt-=makeSet(v[i].first,v[i].second),res.push_back(cnt); 33 for(int i=res.size()-1;i>=0;i--) 34 printf("%d ",res[i]); 35 } 36 return 0; 37 }

    题意:  

      给出一个有N(0<N<=10000)个顶点的无向图(顶点编号0到N-1), 然后依次给出它的M(0<M<=100000)条边,要求依次输出当删除给出的前k(1<=K<=M)条边后,该图的连通分量总数。

            输入:第一行是N和M,然后是M行数(X,Y)(0<=X,Y<N)表示X与Y有边。

            输出:依次输出所求的连通分量数。

    分析:

            当删除前K条边时图所剩的连通分量数 就是 N个点孤立时只添加后M-K条边时,所具有的连通分量数。

            所以仅需倒序插入每条边,分别保存插入边后新图所具有的连通分量数目在数组内,然后输出数组即可。

    (以上摘自http://blog.csdn.net/u013480600/article/details/18278857)


    cin和scanf混用是大坑,并且并不知道需要scanf("%d%d",&num,&line)==2来作为结束条件,题目没有说明啊(?)

    撇开这些,

    • 20行,修改初始化,因为题目节点是从0开始的。
    • 12,14,32行,直接计算结果避免再次遍历数组计算连通节点数
    • 22,30行,根据题意,破坏最后一个道路,必定是num个连通节点
    • 31行,循环到i=1终止,是因为一开始就破坏第一条道路,所以不连接也没事。
    • 33行,根据题意倒序输出

    需要学习一下pair的用法

  • 相关阅读:
    用户态和内核态
    Spring Cloud构建微服务架构:服务网关(路由配置)【Dalston版】
    为什么说分布式事务不再适用于微服务架构
    基于selenium的二次开发
    Python常用方法
    深入浅出runloader
    python socket
    python API接口测试框架
    python装饰器
    python多进程安全
  • 原文地址:https://www.cnblogs.com/Jiiiin/p/8586344.html
Copyright © 2020-2023  润新知