• 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
  • 相关阅读:
    写MBA毕业论文有感-重口味,不喜莫入
    Android中级第三讲如何复用AlertDialog
    Android初级开发第二讲项目学习
    那些消失的计算机技术(一)
    Android中级第一讲如何学习Android自带的demo项目
    Java基础之continue与break区别
    刨根问底系列之C++ const 挖掘
    Unity3d http 通信
    Windows Phone 7 不温不火学习之《启动器与选择器》
    Windows Phone7 不温不火学习之《应用程序生命周期》
  • 原文地址:https://www.cnblogs.com/mrclr/p/9663563.html
Copyright © 2020-2023  润新知