zoukankan      html  css  js  c++  java
  • 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的用法

  • 相关阅读:
    EBS中的采购单据状态及其控制
    详解EBS接口开发之采购接收&退货处理之关键API--(补充)
    数据挖掘系列
    如果看了这篇文章你还不懂傅里叶变换,那就过来掐死我吧
    机器学习中的数学
    一个机器学习博客 ,包括 Standford公开课machine learning
    机器学习流行算法一览
    java se 另一博客
    java 正则
    java map
  • 原文地址:https://www.cnblogs.com/Jiiiin/p/8586344.html
Copyright © 2011-2022 走看看