题目链接:http://codeforces.com/problemset/problem/659/E
给你n个点,m条双向边,然后让你把这些边变成有向边,使得最后的图中入度为0的点的个数最少,求最少的点的个数;
我们很容易的看出当一个点所在的图中存在环时,那么这里面的所有点都可以入度不为0,当不存在的时候最少有一个点的入度为0;
dfs学的不好,所以没做出来;
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <stack> #include <map> #include <vector> using namespace std; typedef long long LL; #define N 100100 #define met(a, b) memset(a, b, sizeof(a)) int flag, vis[N], n, f[N]; vector<vector<int> >G; void dfs(int u, int fa) { if(vis[u])///当再次访问过这个点的时候说明存在环了 { flag = 1; return; } vis[u] = 1; f[u] = fa;/// int len = G[u].size(); for(int i=0; i<len; i++) { int v = G[u][i]; if( f[u]!=v ) dfs(v, u); } } int main() { int m, u, v; while(scanf("%d %d", &n, &m)!=EOF) { G.clear(); G.resize(n+5); met(vis, 0); met(f, -1); for(int i=1; i<=m; i++) { scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } int ans = 0; for(int i=1; i<=n; i++) { if(!vis[i])///当这个点还没被访问过时; { flag = 0; dfs(i, -1); if(!flag) ans++; } } printf("%d ", ans); } return 0; }