题目大意:
给你N个点,M条无向边(没有重边),让你将这M条无向边规定方向变成有向边,使得最终的有向图中,入度为0的点最少,问最少有多少个。
思路:
对于一个联通块而言,如果其中有环存在,那么对应就一定要把这个环规定为强连通分量(并且形状就是一个环)。那么接下来剩余的部分我们只要从这个强连通分量中的点连出即可,使得整个连通块部分没有入度为0的部分,相反,如果一个联通块没有环存在,那么我们规定一个点作为入度为0的点,将其相关的边连出即可,这样就能保证其他的点的入度一定不为0。
那么接下来的实现我们Dfs判断这个无向图的各个连通部分是否存在环即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
int n,m,flag;
vector<int >mp[100060];
int vis[100060];
void Dfs(int u,int from)
{
vis[u]=1;
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(v==from)continue;
if(vis[v]==1)
{
flag=1;
continue;
}
Dfs(v,u);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)mp[i].clear();
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
}
int output=0;
for(int i=1;i<=n;i++)
{
if(vis[i]==0)
{
flag=0;
Dfs(i,-1);
if(flag==0)output++;
}
}
printf("%d\n",output);
}
}