luogu P1262 间谍网络
Posted mrclr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1262 间谍网络相关的知识,希望对你有一定的参考价值。
建图还是很明显的。
接着分两种情况:
1.图中不存在环:那么只要收买那些入度为0的点。如果这些点有的不能收买。就不能控制所有间谍。
2.图中存在环,那么对于这些在环中的点,我们只要收买数额最少的间谍。
于是我们用tarjan缩点:这样把第二种情况就变成了第一种情况。
所以大体流程是:用tarjan缩点,然后统计新图中入度为0的点愿意收买的数额。缩点的时候可以顺便维护每一个强联通分量的数额的最小值以及编号最小的节点。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(‘ ‘) 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 2e4 + 5; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ‘ ‘; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) {ans = ans * 10 + ch - ‘0‘; ch = getchar();} 27 if(last == ‘-‘) ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar(‘-‘); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + ‘0‘); 35 } 36 37 int n, m, r, a[maxn]; 38 vector<int> v[maxn]; 39 40 bool in[maxn]; 41 int dfn[maxn], low[maxn], cnt = 0; 42 stack<int> st; 43 int ccol = 0, col[maxn], val[maxn], Min[maxn]; 44 void tarjan(int now) 45 { 46 dfn[now] = low[now] = ++cnt; 47 st.push(now); in[now] = 1; 48 for(int i = 0; i < (int)v[now].size(); ++i) 49 { 50 if(!dfn[v[now][i]]) 51 { 52 tarjan(v[now][i]); 53 low[now] = min(low[now], low[v[now][i]]); 54 } 55 else if(in[v[now][i]]) low[now] = min(low[now], dfn[v[now][i]]); 56 } 57 if(dfn[now] == low[now]) 58 { 59 int x; 60 ++ccol; 61 do 62 { 63 x = st.top(); st.pop(); 64 in[x] = 0; 65 col[x] = ccol; 66 val[ccol] = min(val[ccol], a[x]); 67 Min[ccol] = min(Min[ccol], x); 68 69 }while(x != now); 70 } 71 } 72 73 int du[maxn]; 74 void newGraph(int now) 75 { 76 int u = col[now]; 77 for(int i = 0; i < (int)v[now].size(); ++i) 78 { 79 int e = col[v[now][i]]; 80 if(u == e) continue; 81 du[e]++; 82 } 83 } 84 85 int main() 86 { 87 n = read(); m = read(); 88 for(int i = 1; i <= n; ++i) a[i] = val[i] = Min[i] = INF; 89 for(int i = 1; i <= m; ++i) 90 { 91 int x = read(), y = read(); 92 a[x] = y; 93 } 94 r = read(); 95 for(int i = 1; i <= r; ++i) 96 { 97 int x = read(), y = read(); 98 v[x].push_back(y); 99 } 100 for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i); 101 for(int i = 1; i <= n; ++i) newGraph(i); 102 int sum = 0, Mn = INF; 103 for(int i = 1; i <= ccol; ++i) if(!du[i]) 104 { 105 if(val[i] == INF) Mn = min(Mn, Min[i]); //如果这个点不能收买 106 else sum += val[i]; 107 } 108 if(Mn != INF) printf("NO %d ", Mn); 109 else printf("YES %d ", sum); 110 return 0; 111 } 112
以上是关于luogu P1262 间谍网络的主要内容,如果未能解决你的问题,请参考以下文章