【CodeForces】【搜索】999E Reachability from the Capital
程序员文章站
2022-05-15 14:02:58
...
CodeForces 999E Reachability from the Capital
题目
题目大意
给定三个正整数,,,表示图中一共有个节点,表示有条边,是个节点中的一个,并给定条单向边,求至少需要加几条单向边,使得从出发,能够到达所有其他节点。
思路
一看就是一个求连通块的变形问题。
然后就交给DFS了。
实现细节
注意:可能会出现如下一种情况:(灵魂画手就是我)
若,当我们按常规方法找出连通块,即按节点编号从小到大的顺序去遍历图,则我们可以得到连通块:和,但实际上,这里只有一个连通块!
所以,我们应允许改变每个节点的连通分量!
注意:由于上面这种方法,我们在输出答案时应计算出有多少不同的连通分量,答案即将它减一(极易用贪心方法说明)。
正解代码
#include<cstdio>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
const int Maxn=5000;
int N,M,S;
vector<int> G[Maxn+5];
void AddEdge(int u,int v) {
G[u].push_back(v);
}
int vis[Maxn+5];
int cnt;
void DFS(int u) {
vis[u]=cnt;
for(int i=0;i<G[u].size();i++) {
int v=G[u][i];
if(vis[v]==cnt||v==S)continue;
DFS(v);
}
}
set<int> tmp;
int GetAns() {
for(int i=1;i<=N;i++)
tmp.insert(vis[i]);
return tmp.size()-1;
}
int main() {
#ifdef LOACL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
scanf("%d %d %d",&N,&M,&S);
for(int i=1;i<=M;i++) {
int u,v;
scanf("%d %d",&u,&v);
AddEdge(u,v);
}
cnt=1;DFS(S);
for(int i=1;i<=N;i++)
if(!vis[i]) {
cnt++;
DFS(i);
}
printf("%d\n",GetAns());
return 0;
}
推荐阅读
-
【CodeForces】【搜索】999E Reachability from the Capital
-
codeforces 999E Reachability from the Capital targan+缩点
-
CodeForces ~ 999E ~ Reachability from the Capital (思维 + 图的DFS)
-
Codeforces Round #490 (Div. 3) E. Reachability from the Capital(tarjan+连通图)
-
CF999E Reachability from the Capital dfs graph greedy
-
Codeforces 999 - E. Reachability from the Capital(trajan+缩点)
-
999E - Reachability from the Capital(Codeforces Round #490 (Div. 3))
-
Reachability from the Capital
-
Codeforces999E——Reachability from the Capital
-
Reachability from the Capital