题目地址:http://codeforces.com/contest/1253/problem/D
题意:给你两个数,n 和 m 。分别代表n个点,m条边。如果 l 和 r 表示n中的某两个点,且这两个点相通,则在(l,r)中的任意数要与l相通,不满足的话就加边,问最少加多少条边满足条件。
思路:dfs已经相通的点,加一个标记,找到当前集合中的最大的那个点x,小于x且与这个集合不相通的点都是要加一条边的,若本身已有集合,也是能被dfs在加边后直接合并的。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 typedef long long ll; 8 const int N=200005; 9 int mk[N],n,m,cnt=1; 10 int num=1; 11 vector<int>g[N]; 12 void dfs(int tm){ 13 mk[tm]=1; 14 cnt=max(cnt,tm); 15 //dfs所有与之相连的点,总边数是不超过200000,所以不用担心超时 16 for(auto i : g[tm]) if(!mk[i]) dfs(i); //auto可改为int 17 } 18 void sol(){ 19 int ans=0; 20 while(num<=n){ 21 while(mk[num]) num++; //遍历找不相通的 22 if(num<cnt) ans++; 23 dfs(num); 24 } 25 cout<<ans<<endl; 26 } 27 int main(){ 28 cin>>n>>m; 29 int u,v; 30 for(int i=0;i<m;i++){ 31 cin>>u>>v; 32 g[u].push_back(v); 33 g[v].push_back(u); 34 } 35 sol(); 36 return 0; 37 }
auto : 这东西的确好用,代码不长,作用却大。
知道后面元素的类型 auto 可以用定义关键词代替的,这里的auto改成 int 也行。但这样有什么坏处和好处就不知道了,还在学习阶段,谅解。