改变道路
题目描述
有n个城市和m条道路,每条道路连接两个城市。每条道路都是单向的,
但你可以决定每条道路的方向。一个城市如果没有通向它的道路,
就被认为是独立的,但允许有从这个城市通往其他城市的道路。
请问最小的独立城市的数量。
输入
第一行输入两个数字n,m。表示城市的数量和道路的数量。
接下来m行每行两个数字u,v,表示u,v两座城市中有一条道
路相连。
(2 ≤ n ≤ 100 000, 1 ≤ m ≤ 100 000).
输出
输出一个数字,表示独立城市的最小数量。
样例输入
【样例输入1】
4 3
2 1
1 3
4 3
【样例输入2】
5 5
2 1
1 3
2 3
2 5
4 3
【样例输入3】
6 5
1 2
2 3
4 5
4 6
5 6
样例输出
【样例输出1】
1
【样例输出2】
0
【样例输出3】
1
题解:
细分析题目,一条边最多只能使一个城市变成非独立城市。那么,如果几个城市中不存在环,那么至少有一个城市是独立城市,如果有环,多余的边即可将剩余的城市变成非独立城市,画图也可得出此结论。
那么,我们只需判断无向图中所有联通块是否存在环。我们可以o(n)循环遍历所有点,如果点未被访问过,dfs查询是否有联通块即可。时间复杂度O(n)
源代码:
(有些空需填)
#include <bits/stdc++.h>
using namespace std;
int n,m,ans,ans1;
bool vis[100005];
vector<______> vec[100005];
void dfs(int pos,int pre) {
if(vis[pos]) {
ans1=0;
return ;
}
vis[pos]=1;
for(______) {
if(vec[pos][i]!=pre)
dfs(vec[pos][i],pos);
}
}
int main() {
scanf("%d%d",&n,&m);
for(______) {
int a,b;
scanf("%d%d",&a,&b);
vec[a].push_back(b);
vec[b].push_back(a);
}
for(int i=1; i<=n; i++) {
if(vis[i])
continue;
else {
ans1=1;
dfs(i,0);
ans=ans+ans1;
}
}
printf("%d\n",ans);
return 0;
}