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  
View Code

 

以上是关于luogu P1262 间谍网络的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1262 间谍网络 题解

洛谷——P1262 间谍网络

洛谷 P1262 间谍网络

洛谷 P1262 间谍网络==Codevs 4093 EZ的间谍网络

洛谷P1262 间谍网络

洛谷 P1262 间谍网络