1 solutions
-
0
#include<bits/stdc++.h> using namespace std; /* 题目大意: n个点和m条边的有向图,每条边都有激活和失活两种状态,初始时均为激活状态,有四种操作: 1.失活某条边; 2.失活以某个点为终点的所有边; 3.激活某条边; 4.激活以某个点为终点的所有边 问:如果只考虑激活的边,是否满足所有的点的出度均为1 解法1:模拟-时间复杂度O(nq)-80pts */ const int N = 5e5 + 10; int out[N];//统计每一个点的出度 struct point { int u, isvalid; }; vector<point> g[N];//邻接表 int main() { int n, m, q; cin >> n >> m; //建图 while (m--) { int u, v; scanf("%d%d", &u, &v); out[u]++; g[v].push_back({ u,1 });//反向建图 } //初步统计出度为1的点的数量 int cnt = 0; for (int i = 1; i <= n; i++) if (out[i] == 1) cnt++; cin >> q; while (q--) { int opt; scanf("%d", &opt); if (opt == 1) {//失活u-v这条边 int u, v; scanf("%d%d", &u, &v); if (out[u] == 1) cnt--; out[u]--; if (out[u]==1) cnt++; for (auto& e : g[v]) if (e.u == u) e.isvalid = 0; } else if (opt == 2) {//失活以某个点为终点的所有边; int v; scanf("%d", &v); for (auto& e : g[v]) { if (e.isvalid != 0) { e.isvalid = 0; int u = e.u; if(out[u] == 1) cnt--; out[u]--; if (out[u] == 1) cnt++; } } } else if (opt == 3) {//激活u-v这条边 int u, v; scanf("%d%d", &u, &v); if (out[u] == 1) cnt--; out[u]++; if (out[u] == 1) cnt++; for (auto& e : g[v]) if (e.u == u) e.isvalid = 1; } else if (opt == 4) {//激活以某个点为终点的所有边; int v; scanf("%d", &v); for (auto& e : g[v]) { if (e.isvalid == 0) { e.isvalid = 1; int u = e.u; if (out[u] == 1) cnt--; out[u]++; if (out[u] == 1) cnt++; } } } printf("%s\n", cnt == n ? "YES" : "NO"); } return 0; }
Information
- ID
- 1152
- Time
- 4000ms
- Memory
- 256MiB
- Difficulty
- 10
- Tags
- # Submissions
- 15
- Accepted
- 1
- Uploaded By