首页 > 其他分享 >洛谷P1262 间谍网络(tarjan求强连通分量+缩点)

洛谷P1262 间谍网络(tarjan求强连通分量+缩点)

时间:2022-09-06 19:34:07浏览次数:71  
标签:缩点 tarjan 洛谷 int void scccnt low include

题目链接:https://www.luogu.com.cn/problem/P1262  

思路:首先,我们能够知道,入读为0 的点 如果不能被收买的话,那么此题是无解的。其次,如果图中存在环的话,那么环中每个点的最小值 就是这个环所成的点的值,环中每个点是相互可以到达的,而且如果环处在中间的话,我们是可以无视掉的,我们只考虑环在开头的情况,也就是缩点之后,入读为0的点。通过tarjan求出强连通分量后进行缩点,然后计算入读为0的点所花费的金额就ok了。

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<vector>
  4 #include<map>
  5 #include<queue>
  6 #include<set>
  7 #include<algorithm>
  8 #include<stack>
  9 #include<cmath>
 10 #include<cstring>
 11 #include<string>
 12 using namespace std;
 13 #define gc getchar()
 14 #define rd(x) read(x)
 15 #define el '\n'
 16 #define rep(i, a, n) for(int i = (a); i <= n; ++i)
 17 #define per(i, a, n) for(int i = (a); i >= n; --i)
 18 using ll = long long;
 19 using db = double;
 20 using ldb = long double;
 21 const int mod = 1e9 + 7;
 22 const int inf = 0x3f3f3f3f;
 23 const int N = 100000 + 10;
 24 
 25 template <typename _T>
 26 inline void read(_T& f) {
 27     f = 0; _T fu = 1; char c = gc;
 28     while (c < '0' || c > '9') { if (c == '-') { fu = -1; } c = gc; }
 29     while (c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = gc; }
 30     f *= fu;
 31 }
 32 
 33 template <typename T>
 34 void print(T x) {
 35     if (x < 0) putchar('-'), x = -x;
 36     if (x < 10) putchar(x + 48);
 37     else print(x / 10), putchar(x % 10 + 48);
 38 }
 39 
 40 template <typename T>
 41 void print(T x, char t) {
 42     print(x); putchar(t);
 43 }
 44 
 45 int dfn[N], low[N], ins[N], scc[N], in[N];
 46 int dfncnt, scccnt;
 47 stack<int>st;
 48 vector<int>G[N];
 49 vector<int>DAG[N];
 50 int vi[N];
 51 int coin[N];
 52 int vp[N];
 53 
 54 int n, m, p;
 55 int pmax;
 56 
 57 void tarjan(int u) {
 58     dfn[u] = ++dfncnt;
 59     low[u] = dfncnt;
 60     st.push(u);
 61     ins[u] = true;
 62     for (int i = 0; i < G[u].size(); i++) {
 63         int v = G[u][i];
 64         if (!dfn[v]) {
 65             tarjan(v);
 66             low[u] = min(low[u], low[v]);
 67         }
 68         else if (ins[v]) {
 69             low[u] = min(low[u], dfn[v]);
 70         }
 71     }
 72     if (dfn[u] == low[u]) {
 73         int v;
 74         ++scccnt;
 75         pmax = max(pmax, scccnt);
 76         do {
 77    A         v = st.top();
 78             st.pop();
 79             ins[v] = false;
 80             scc[v] = scccnt;
 81             coin[scccnt] = min(coin[scccnt], vi[v]);
 82             vp[scccnt] = min(vp[scccnt], v);
 83 
 84         } while (u != v);
 85     }
 86 }
 87 
 88 void getdag() {
 89     for (int i = 1; i <= n; i++) {
 90         if (!dfn[i]) {
 91             tarjan(i);
 92         }
 93     }
 94     for (int u = 1; u <= n; u++) {
 95         for (int j = 0; j < G[u].size(); j++) {
 96             int v = G[u][j];
 97             if (scc[u] != scc[v]) {
 98                 DAG[scc[u]].push_back(scc[v]);
 99                 in[scc[v]]++;
100             }
101         }
102     }
103 }
104 
105 int main() {
106 
107     ios::sync_with_stdio(false);
108     cin.tie(0), cout.tie(0);
109     //int n, m;
110     cin >> n;
111     cin >> p;
112     memset(vp, 0x3f, sizeof(vp));
113     memset(coin, 0x3f, sizeof(coin));
114     memset(vi, 0x3f, sizeof(vi));
115     for (int i = 1; i <= p; i++) {
116         int a, b;
117         cin >> a >> b;
118         vi[a] = b;
119     }
120     cin >> m;
121     for (int i = 1; i <= m; i++) {
122         int u, v;
123         cin >> u >> v;
124         G[u].push_back(v);
125     }
126     getdag();
127     int ans = 0;
128     for (int i = 1; i <= pmax; i++) {
129         if (!in[i]) {
130             if (coin[i] == inf) {
131                 cout << "NO" << el;
132                 cout << vp[i] << el;
133                 return 0;
134             }
135             ans += coin[i];
136         }
137     }
138     cout << "YES" << el;
139     cout << ans << el;
140 
141     return 0;
142 }

 

 

标签:缩点,tarjan,洛谷,int,void,scccnt,low,include
From: https://www.cnblogs.com/wabi/p/16663085.html

相关文章

  • 洛谷P2002 消息扩散(tarjan缩点)
    题目链接:https://www.luogu.com.cn/problem/P2002思路:由于图中每个强连通分量(scc)中的点是可以互相到达的,所以我们可以用tarjan求图中scc,然后将所有scc缩点,最后求缩点之......
  • 洛谷 P1036 [NOIP2002 普及组] 选数(dfs)
    https://www.luogu.com.cn/problem/P1036题目大意:从给定的n个数中选出m个求和,结果是一个素数的情况有多少种?输入43371219输出1这个题目的代码是根据Acwing中......
  • 洛谷P1558 色板游戏 题解
    高考完后随机跳题的复建运动。看到区间覆盖操作考虑线段树。30种颜色?用位运算存储节省空间。因为在线段树上传合并时只需要考虑这一段是否存在该颜色,(即\(0\)或\(1\))具体......
  • 洛谷P1850 [NOIP2016 提高组] 换教室(期望dp)
    #include<bits/stdc++.h>usingnamespacestd;intn,m,v,e;intc[3005],d[3005];intf[305][305];doubledp[3005][3005][2];//dp[i][j][k]表示前i步申请更换了j......
  • 洛谷P7907 [Ynoi2005] rmscne
    数据结构好题首先将询问离线,扫描线扫答案区间的左端点。设和\(l\)颜色相同的下一个位置为\(x\)。那么对于左端点\(\leql\),\(l\leq\)右端点$<x$的询问,\(l\)......
  • 洛谷深基hash表
    洛谷深基hash表字符串哈希给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。我们不妨先分......
  • 缩点后 spfa求最长路(不知道为什么top+dp做不了)
    #include<queue>#include<cstdio>#include<cstring>#defineN500005usingnamespacestd;structedge{intto,val,next;}e[N];intm,n,p,s,cnt,g[N],u[N],v......
  • [洛谷P5787] 线段树时间分治
    题目大意给\(n\)个点\(m\)条边,在\(k\)时间内,第\(i\)条边只在\([l_i+1,r_i]\)的时间范围内存在。对于每个\(i\leqk\),输出\(i\)时刻这个图是否是二分图。题......
  • 学习随笔——洛谷题目P1636解答
    摘要:欧拉图的应用。题目原地址如下:https://www.luogu.com.cn/problem/P1636题目截图如下:  一笔画问题,考察欧拉回路的定义,即所有节点的入度出度的和都为偶数即可满足......
  • 洛谷 P6862 [RC-03] 随机树生成器 绿 题解
    前言模数要模\(1e9+9\)!!模数要模\(1e9+9\)!!模数要模\(1e9+9\)!!结论\(n\)个点的树的形态有\((n-1)!\)个,对于节点\(k\),它的所有度数和为\((n-1)!\left(\sum\limits_{......