日期:2023.10.21
第9天
题目来源:洛谷P2583
代码:
/* 遍历图的所有顶点,找到这样的顶点,它可以到达一些已经给出的顶点; 直接暴力法:依次计算每一个点,判断这个点可以遍历的所有点中,是否包含了所有已给出的点,注意 这个点可以遍历的点,包括他自己; 遍历所有点,找到能到达这个点的所有点:反向建边 ;看这些点中是否包含了奶牛所在的所有点 */ #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int MAXN = 1010; const int INF = 0x3f3f3f3f; int k, n, m; int G[MAXN][MAXN]; int cow[MAXN];//存放奶牛所在的位置 vector<int> v[MAXN];//每一个点,可以到达的所有点的集合 int ans = 0;//答案结点 bool vis[MAXN] = {0}; //这个DFS()的逻辑第一次时有问题; void DFS(int u, int now) { //将能到达now的点,加入到 v[u]中;最开始的时候now就是u, v[u].push_back(now); //可以到达u的点 vis[now] = 1; //遍历所有可以到达u的点 for(int i = 1; i <= n ; i++) { if(G[i][now] == 1 && vis[i] == 0) { //如果i->now存在,就把i加入 DFS(u, i); } } } int main(void) { memset(G, 0x3f, sizeof(G)); scanf("%d%d%d", &k, &n, &m); for(int i = 0; i < k; i++) { scanf("%d", &cow[i]); } for(int i = 0; i < m; i++) { int v1, v2; scanf("%d%d", &v1, &v2); G[v1][v2] = 1; } for(int i = 1; i <= n; i++) { memset(vis, 0, sizeof(vis)); DFS(i, i); } // for(int i = 0; i < k; i++) { // cout << "cow" << i << ' ' << cow[i] << ' '; // } // cout << endl; // // for(int i = 1; i <= n; i++) { // cout << "顶点" << i << ' '; // for( int j = 0; j < v[i].size(); j++) { // cout << v[i][j] << ' '; // } // cout << endl; // } for(int i = 1; i <= n; i++) { //检验n个顶点 bool f = 1; for(int j = 0; j < k; j++) { //判断奶牛所在的每个顶点是否可以到达 if(find(v[i].begin(), v[i].end(), cow[j]) == v[i].end()) { //有一个没找到,就退出,并且标记 f = 0; break; } } if(f == 1) { ans++; } } printf("%d", ans); return 0; }
问题:
1.今天做题有些松懈了,没有仔细思考逻辑;
2.需要实现,能到达一个点的所有点,区别与正常写的,这个点能到达的所有点;因为这个问题DFS的逻辑错误;