USACO Street Race 解题报告

来源:互联网 发布:炫踪网络红杉 编辑:程序博客网 时间:2024/05/18 02:25

这道题要求找出所有的unavoidable points和splitting points. 定义虽然抽象,但实现起来很简单。

unavoidable points指的是从起点到终点必须经过点,验证的办法是取掉这个点后看能否从起点到终点。具体而言,就是在从起点进行DFS之前将这个点visited标记成true,DFS之后看是否有任何一个点没有被visited.直接查看终点应该也是可行的。

splitting points指的是从这些点分开后可以形成前后两个"赛程",且这两个赛程之间没有公共边,只有这一个公共点。首先,splitting points必须是unavoidable points.如果一个point不是unavoidable,那么分开成两个赛程后,有一个点仍然可以同时从起点和splitting point到达,这个点就是两个赛程的公共点,与定义不符。其次,依据相同的思路,我们可以从splitting points出发,再跑一次DFS,然后看看与之前那次DFS(从起点出发)有没有公共点,即都能到达的点,如果没有,我们可以得出,这样点符合splitting point的定义。

/* ID: thestor1 LANG: C++ TASK: race3 */#include <iostream>#include <cmath>#include <cstdio>#include <cstring>#include <climits>#include <cassert>#include <string>#include <vector>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>using namespace std;void DFS(int v, std::vector<bool> &visited, const vector<vector<int> > &adjs){visited[v] = true;for (int i = 0; i < adjs[v].size(); ++i){if (!visited[adjs[v][i]]){DFS(adjs[v][i], visited, adjs);}}}int main(){FILE *fin  = fopen("race3.in", "r");FILE *fout = fopen("race3.out", "w");std::vector<vector<int> > adjs;while (true){std::vector<int> neighbours;int v;fscanf(fin, "%d", &v);if (v == -1){break;}while (v != -2){neighbours.push_back(v);fscanf(fin, "%d", &v);}adjs.push_back(neighbours);}    std::vector<int> unavoidables, splittings;    std::vector<bool> visited(adjs.size(), false);for (int u = 1; u < adjs.size() - 1; ++u){for (int v = 0; v < visited.size(); ++v){visited[v] = false;}visited[u] = true;DFS(0, visited, adjs);        bool unavoidable = false;for (int v = 0; v < visited.size(); ++v){if (!visited[v]){unavoidable = true;break;}}        if (unavoidable){unavoidables.push_back(u);            std::vector<bool> reachable(adjs.size(), false);DFS(u, reachable, adjs);            bool splitting = true;for (int v = 0; v < adjs.size(); ++v){if (v == u){continue;}if (visited[v] && reachable[v]){splitting = false;break;}}if (splitting){splittings.push_back(u);}}}    fprintf(fout, "%lu", unavoidables.size());for (int i = 0; i < unavoidables.size(); ++i){fprintf(fout, " %d", unavoidables[i]);}fprintf(fout, "\n");    fprintf(fout, "%lu", splittings.size());for (int i = 0; i < splittings.size(); ++i){fprintf(fout, " %d", splittings[i]);}fprintf(fout, "\n");    fclose(fin);fclose(fout);return 0;  }


0 0
原创粉丝点击