题意
题意:给我们n个城市,然后给我们m条边,组成一个无向图,让我们把无向边变成单向边,然后问我们被孤立的城市最小是多少。
思路
首先我们考虑什么情况下是没有孤立城市的,就是有环的时候,这个时候我们任选一个点出发然在出发点结束,这时就是没有孤立城市的(及满足题意就是每一个城市都有至少一个城市可以到达)。那什么情况是有孤立城市的呢,只要是线性的图就必定存在一个孤立点。那么环状图叠线性图呢,那么这个还是没有孤立城市的,我们只需要让叠加点成为出发点即可。综上所述我们只需要找出无环的 子图即可。
现在我们重新翻译一下题意,给我们一个无向图,让我们求出无环的子图有几个。
AC代码
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6 + 10;
int e[N], ne[N], h[N], idx;
bool st[N];
int n, m;
int flag;
void add(int a, int b) //链式前向星建图
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u, int pre)
{
st[u] = true;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == pre)//每一个边一开始都是无向的所以我们应该去除两点之间已经选过的边
continue;
if (st[j] == true) //判断是否已经走过,如果已经走过一遍的话,就说明是有环的
{
flag = 1;
continue;
}
dfs(j, u);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
memset(h, -1, sizeof(h));
while (m--)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (st[i] == false)
{
flag = 0; //设置标记看看是否有环
dfs(i, 0);
if (flag == 0)
ans++;
}
}
cout << ans << endl;
return 0;
}