D. Mouse Hunt
https://codeforces.com/problemset/problem/1027/D
思路
考察ssc检测算法
每个宿舍对应下图中一个点,
由于老鼠从每个宿舍出发,只能到达一个宿舍, 则有向图中存在的 强连通子图 只可能是环,如下图
在检测出的强连通子图中, cost最小的宿舍里设置trap,可保证进入此强连通子图的耗子 死翘翘!!
有几个size大于2的强连通子图, 在子图中设置几个trap。
同时注意, 对于老鼠待着不动宿舍, 也需要设置一个trap。
Code
https://codeforces.com/problemset/submission/1027/194456641
#include <iomanip> #include <bits/stdc++.h> #include <iostream> using namespace std; #include <limits.h> #include <math.h> #include <vector> #include <set> #include <map> #include <stack> #include <queue> typedef long long LL; typedef pair<int, int> pii; typedef pair<LL, LL> pll; typedef pair<string, string> pss; typedef vector<int> vi; typedef vector<vi> vvi; typedef vector<pii> vii; typedef vector<LL> vl; typedef vector<vl> vvl; double EPS = 1e-9; int INF = 1000000005; long long INFF = 1000000000000000005LL; double PI = acos(-1); int dirx[8] = { -1, 0, 0, 1, -1, -1, 1, 1 }; int diry[8] = { 0, 1, -1, 0, -1, 1, -1, 1 }; #ifdef TESTING #define DEBUG fprintf(stderr, "====TESTING====\n") #define VALUE(x) cerr << "The value of " << #x << " is " << x << endl #define debug(...) fprintf(stderr, __VA_ARGS__) #else #define DEBUG #define VALUE(x) #define debug(...) #endif #define FOR(a, b, c) for (int(a) = (b); (a) < (c); ++(a)) #define FORN(a, b, c) for (int(a) = (b); (a) <= (c); ++(a)) #define FORD(a, b, c) for (int(a) = (b); (a) >= (c); --(a)) #define FORSQ(a, b, c) for (int(a) = (b); (a) * (a) <= (c); ++(a)) #define FORC(a, b, c) for (char(a) = (b); (a) <= (c); ++(a)) #define FOREACH(a, b) for (auto&(a) : (b)) #define REP(i, n) FOR(i, 0, n) #define REPN(i, n) FORN(i, 1, n) #define MAX(a, b) a = max(a, b) #define MIN(a, b) a = min(a, b) #define SQR(x) ((LL)(x) * (x)) #define RESET(a, b) memset(a, b, sizeof(a)) #define fi first #define se second #define mp make_pair #define pb push_back #define ALL(v) v.begin(), v.end() #define ALLA(arr, sz) arr, arr + sz #define SIZE(v) (int)v.size() #define SORT(v) sort(ALL(v)) #define REVERSE(v) reverse(ALL(v)) #define SORTA(arr, sz) sort(ALLA(arr, sz)) #define REVERSEA(arr, sz) reverse(ALLA(arr, sz)) #define PERMUTE next_permutation #define TC(t) while (t--) /******************************** COMMON FUNC START ***************************************/ LL quick_pow(LL x,LL n,LL m){ LL res = 1; while(n > 0){ if(n & 1) res = res * x % m; x = x * x % m; n >>= 1;//相当于n=n/2.详情请参考位移运算符。 } return res; } inline string IntToString(LL a) { char x[100]; sprintf(x, "%lld", a); string s = x; return s; } inline LL StringToInt(string a) { char x[100]; LL res; strcpy(x, a.c_str()); sscanf(x, "%lld", &res); return res; } inline string GetString(void) { char x[1000005]; scanf("%s", x); string s = x; return s; } inline string uppercase(string s) { int n = SIZE(s); REP(i, n) if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 'a' + 'A'; return s; } inline string lowercase(string s) { int n = SIZE(s); REP(i, n) if (s[i] >= 'A' && s[i] <= 'Z') s[i] = s[i] - 'A' + 'a'; return s; } inline void OPEN(string s) { #ifndef TESTING freopen((s + ".in").c_str(), "r", stdin); freopen((s + ".out").c_str(), "w", stdout); #endif } /******************************** COMMON FUNC END ***************************************/ /******************************** GRAPH START ***************************************/ // Graph class represents a directed graph // using adjacency list representation class Graph { public: map<int, bool> visited; map<int, list<int> > adj; // function to add an edge to graph void addEdge(int v, int w); // DFS traversal of the vertices // reachable from v void DFS(int v); }; void Graph::addEdge(int v, int w) { adj[v].push_back(w); // Add w to v’s list. } void Graph::DFS(int v) { // Mark the current node as visited and // print it visited[v] = true; cout << v << " "; // Recur for all the vertices adjacent // to this vertex list<int>::iterator i; for (i = adj[v].begin(); i != adj[v].end(); ++i) if (!visited[*i]) DFS(*i); } /******************************** GRAPH END ***************************************/ /* https://atcoder.jp/contests/abcxxx/tasks/abcxxx_d */ int n; map<int, map<int, bool> > g, rg; // label node as visited vector<bool> vis; // pv : post visit // store node by post visit order stack<int> pv; // color node to indicate one component map<int, int> color; // cost for each room to setup trap map<int, int> cost; // the order of strongly connected component int sscCnt = 0; map<int, set<int> > ssc; void dfs(int i){ vis[i] = true; for(auto it: g[i]){ int next = it.first; if (!vis[next]){ dfs(next); } } pv.push(i); } void rdfs(int i){ color[i] = sscCnt; ssc[sscCnt].insert(i); for(auto it: rg[i]){ int next = it.first; if (!color[next]){ rdfs(next); } } } int main() { cin >> n; for(int i=1; i<=n; i++){ int c; cin >> c; cost[i] = c; } vector<int> stays; for(int u=1; u<=n; u++){ int v; cin >> v; if (u == v){ stays.push_back(u); } g[u][v] = true; rg[v][u] = true; } // cout << "after g rg done ---" << endl; // index from 1 to align with node numbers: 1 ~ n vis.push_back(false); for(int i=1; i<=n; i++){ vis.push_back(false); } // cout << "after g rg done ---" << endl; // visit on g to get pv for(int i=1; i<=n; i++){ if(!vis[i]){ dfs(i); } } // visit on rg to get sscCnt while(!pv.empty()){ int top = pv.top(); pv.pop(); if (!color[top]){ ++sscCnt; rdfs(top); } } // for(auto it: ssc){ // int sscIndex = it.first; // set<int>& nodes = it.second; // // cout << "ssc" << sscIndex << ":"; // for(auto nit: nodes){ // cout << nit << " "; // } // cout << endl; // } long long sumc = 0; for(int i=1; i<=sscCnt; i++){ // cout << "ssc[i].size() = " << ssc[i].size() << endl; if(ssc[i].size() <= 1){ continue; } int minc = INT_MAX; for(auto it: ssc[i]){ // cout << "it=" << it << endl; minc = min(cost[it], minc); } sumc += minc; } int staycost = 0; for(int i=0; i<stays.size(); i++){ int node = stays[i]; staycost += cost[node]; } cout << sumc + staycost << endl; return 0; }
标签:typedef,string,int,void,Hunt,vector,include,Mouse From: https://www.cnblogs.com/lightsong/p/17142509.html