球迷(資料結構作業)
阿新 • • 發佈:2018-12-01
演算法與資料結構實驗題 12.2 球迷
★實驗任務
在福大里,有 n 個學生,每個的學生都有自己喜愛的球星,已知有 m 對學生喜愛的球星相同,問你這 n 個學生喜愛的球星最多有多少個。
★資料輸入
輸入第一行為一個正整數 n,m。
接下來 m 行,每行輸入 ai,bi,表示 ai 同學和 bi 同學喜愛的球星一樣
80%的資料 1<=n,m<=1000.
100%的資料 1<=n,m<=100000.
★資料輸出
輸出一個正整數,表示答案。
輸入示例 |
輸出示例 |
10 9 |
1 |
1 2 |
|
1 3 |
|
1 4 |
|
1 5 |
|
1 6 |
|
1 7 |
|
1 8 |
|
1 9 |
|
1 10 |
|
輸入示例 |
輸出示例 |
10 4 |
7 |
2 3 |
|
4 5 |
|
4 8 |
|
5 8 |
|
兩個方法本質相同:BFS求連通性,並查集求連通性.
方法一:
這道題是典型的圖的搜尋演算法(BFS).用鄰接矩陣實現的話,時間複雜度為O(N+E).
思路:
有著相同喜歡的球星的同學連在一起,形成一個連通子塊。其他的同學作為獨立點(特殊子塊)。求共有多少個連通子塊?
依據BFS的演算法,對從1-n的每一個點遍歷。
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
/*
結構體+可變陣列 模擬鄰接矩陣
*/
struct Graph{
vector <int> v;
};
Graph g[100100]; //圖的陣列
int turn [100100]={0}; //BFS過程中的標記陣列。
void BFS(int i)
{
int x;
queue <int> q;
q.push(i);
vector <int> :: iterator it;
//對節點i,BFS,把和i連在一起的都遍歷一遍。
while(!q.empty())
{
x=q.front();
q.pop();
turn[x]++;
for (it=g[x].v.begin();it!=g[x].v.end();it++)
{
if (turn[*it]==0)
{
q.push(*it);
}
}
}
}
int main()
{
int n,m,x,y,count=0;
scanf ("%d %d",&n,&m);
for (int i=0;i<m;i++)
{
scanf ("%d %d",&x,&y);
g[x].v.push_back(y);
g[y].v.push_back(x);
}
for (int i=1;i<=n;i++)
{
if (g[i].v.empty())
{
count++;
turn[i]++;
}
else
{
if (turn[i]==0)
{
count++;
BFS(i);
}
}
}
printf ("%d\n",count);
return 0;
}
方法2:
經典並查集模型
#include <cstdio>
#include <cstring>
using namespace std;
int s[100010];
int count;
void Make_Set(void)
{
memset(s,-1,sizeof(s)); //初始化所有節點
}
int Find(int x)
{
if (s[x]<=0) //找到根節點,返回
return x;
else
return (s[x]=Find(s[x])); //路徑壓縮,把x到根節點的路徑上的所有節點變成根的兒子
}
void Union(int root1,int root2) //按秩求並
{
root1=Find(root1);
root2=Find(root2);
if (root1==root2) //兩節點連通,退出
return ;
if (s[root2]<s[root1]) //root2樹更深,把root1合併到root2
s[root1]=root2;
else{
if (s[root1]==s[root2]) //相同高度,合併root1高度+1
s[root1]--;
s[root2]=root1; //root2合併到root1
}
count--; //由於兩集合合併,所有子樹數量-1
}
int main()
{
int n,m,a,b,ra,rb;
scanf ("%d %d",&n,&m);
count=n;
Make_Set();
for (int i=0;i<m;i++)
{
scanf ("%d %d",&a,&b);
Union(a,b);
}
printf ("%d\n",count);
return 0;
}