洛谷训练赛 A.Misaka Network
给出一DAG,求最小多少个控制点,能够使得控制图中所有点,控制点可以控制本身和他直接能到的点
题解:只需按拓扑序控制每个点即可
#include<iostream> #include<string> #include<unordered_map> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f const int maxn = 1e5 + 15; const double PI = acos(-1.0); typedef long long ll; using namespace std; int indeg[maxn]; int topo[maxn]; int vis[maxn]; vector<int> vec[maxn]; queue<int> q; int n, m, u, v, num; void topsort() { int cnt = 0; while (!q.empty()) q.pop(); num = 0; for (int i = 1; i <= n; i++) if (!indeg[i]) q.push(i), topo[cnt++] = i; while (!q.empty()) { int now = q.front(); q.pop(); num++; for (int i = 0; i < vec[now].size(); i++) { if (--indeg[vec[now][i]]==0) q.push(vec[now][i]), topo[cnt++] = vec[now][i]; } } } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); vec[u].push_back(v); indeg[v]++; } topsort(); int ans = 0; for (int i = 0; i < n; i++) { if (!vis[topo[i]]) { for (int j = 0; j < vec[topo[i]].size(); j++) vis[vec[topo[i]][j]]++; ans++; } } //for (int i = 0; i < n; i++) printf("%d ", topo[i]); printf("%d", ans); return 0; }