Description
某省調查城鎮交通狀況,得到現有城鎮道路統計表,表中列出了每條道路直接連通的城鎮。省政府“暢通工程”的目標是使全省任何兩個城鎮間都可以實現交通但不一定有直接的道路相連,只要互相間接通過道路可達即可)。問最少還需要建設多少條道路?Input
測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是城鎮數目N ( < 1000 )和道路數目M;隨後的M行對應M條道路,每行給出一對正整數,分別是該條道路直接連通的兩個城鎮的編號。為簡單起見,城鎮從1到N編號。Output
對每個測試用例,在1行裡輸出最少還需要建設的道路數目。Sample Input
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
Sample Output
1
0
2
998
Hint
Hint Huge input, scanf is recommended.
其實就是判斷樹和孤立點的數量
#include<iostream>
#include<vector>
#include<stack>
#include<list>
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m&&n){
vector<list <int > > adj;
int i;
stack<int >st;
vector<bool>visited;
visited.resize(n+1);
for(i=1;i<n+1;i++)
visited[i]=false;
adj.resize(n+1);
for(i=0;i<m;i++){
int a,b;
cin>>a>>b;
adj[a].push_back(b);
adj[b].push_back(a);
}
int forest=0;
for(i=1;i<n+1;i++){
if(visited[i]==false){
if(adj[i].empty())
forest++;
else{
st.push(i);
while(!st.empty()){
int top=st.top();
visited[top]=true;
st.pop();
list<int >::iterator p=adj[top].begin();
while(p!=adj[top].end()){
if(visited[*p]==false){
visited[*p]=true;
int newtop=*p;
st.push(newtop);
}
p++;
}
}
forest++;
}
}
}
cout<<forest-1<<endl;
}
return 0;
}