• 间谍网络(tarjan缩点)


    洛谷传送门


    看着这道题给人感觉就是tarjan求SCC,然而还得判断是否能控制全部间谍,这就得先从可以贿赂的点dfs一遍。

    如果没有全部被标记了,就输出NO,再从没被标记的点里找最小的标号。

    如果全被标记,就输出YES,再从入度为0的缩点里找最小的价格,加到ans中,最后输出ans。

    ——代码

      1 #include <cstdio>
      2 #include <stack>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 
      7 int n, p, r1, cnt, idx, ans = 30000001, minn;
      8 int a[3001], next[8001], to[8001], head[3001], low[3001], dfn[3001], belong[3001], r[3001];
      9 bool ins[3001], vis[3001], mey[3001];
     10 stack <int> s;
     11 
     12 inline void add(int x, int y)
     13 {
     14     to[cnt] = y;
     15     next[cnt] = head[x];
     16     head[x] = cnt++;
     17 }
     18 
     19 void dfs(int u)
     20 {
     21     int i, v;
     22     vis[u] = 1;
     23     mey[u] = 1;
     24     for(i = head[u]; i != -1; i = next[i])
     25     {
     26         v = to[i];
     27         if(!vis[v]) dfs(v);
     28     }
     29 }
     30 
     31 void tarjan(int u)
     32 {
     33     low[u] = dfn[u] = ++idx;
     34     s.push(u);
     35     ins[u] = 1;
     36     int i, v;
     37     for(i = head[u]; i != -1; i = next[i])
     38     {
     39         v = to[i];
     40         if(!dfn[v])
     41         {
     42             tarjan(v);
     43             low[u] = min(low[u], low[v]);
     44         }
     45         else if(ins[v]) low[u] = min(low[u], dfn[v]);
     46     }
     47     if(low[u] == dfn[u])
     48     {
     49         cnt++;
     50         do
     51         {
     52             v = s.top();
     53             s.pop();
     54             ins[v] = 0;
     55             belong[v] = cnt;
     56         }while(u != v);
     57     }
     58 }
     59 
     60 int main()
     61 {
     62     int i, j, k, x, y, u, v;
     63     scanf("%d %d", &n, &p);
     64     for(i = 1; i <= p; i++)
     65     {
     66         scanf("%d", &x);
     67         scanf("%d", &a[x]);
     68     }
     69     memset(head, -1, sizeof(head));
     70     scanf("%d", &r1);
     71     for(i = 1; i <= r1; i++)
     72     {
     73         scanf("%d %d", &x, &y);
     74         add(x, y);
     75     }
     76     for(i = 1; i <= n; i++)
     77      if(!vis[i] && a[i])
     78       dfs(i);
     79     for(i = 1; i <= n; i++)
     80      if(!mey[i])
     81       ans = min(ans, i);
     82     if(ans != 30000001)
     83     {
     84         printf("NO
    %d", ans);
     85         return 0;
     86     }
     87     cnt = 0;
     88     for(i = 1; i <= n; i++)
     89      if(!dfn[i])
     90       tarjan(i);
     91     for(u = 1; u <= n; u++)
     92      for(i = head[u]; i != -1; i = next[i])
     93      {
     94          v = to[i];
     95          if(belong[u] != belong[v]) r[belong[v]]++;
     96      }
     97     ans = 0;
     98     for(i = 1; i <= cnt; i++)
     99      if(r[i] == 0)
    100      {
    101          minn = 30000001;
    102          for(j = 1; j <= n; j++)
    103           if(belong[j] == i && a[j])
    104            minn = min(minn, a[j]);
    105          ans += minn;
    106      }
    107     printf("YES
    %d", ans);
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    Android WebView常见问题及解决方案汇总【很全很实用】
    adb shell dumpsys meminfo [packagename] 输出内容的含义
    Android关于RAM、ROM、SD卡以及各种内存的区别
    每天5分钟玩转容器技术 整理目录
    ubuntu16.04基本设置
    ubuntu镜像快速下载
    vSphere 5.5.0 U1配置问题:主机的快速统计信息不是最新的(转载)
    Vcenter server 5.5安装部署
    SQL Server 2008 R2 数据库安装
    Centos7.3搭建DNS服务器--BIND
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6686375.html
Copyright © 2020-2023  润新知