ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【洛谷P1262】间谍网络

2019-08-24 09:54:29  阅读:197  来源: 互联网

标签:洛谷 int 3010 top st 间谍 low P1262 col


Description

给定n个点 其中p个点可以被贿赂, 被贿赂的金额为x,如果一个点被贿赂,他所指向的点也会被贿赂

求:如果不能全部被贿赂 输出NO以及不能被贿赂的点 否则输出YES和需要支付的金额的最小值

Solution

我们可以通过tarjan缩点,最后扫一遍dfn,若果有一个点并没有被访问过,说明这个点肯定不会被贿赂 直接输出并结束程序

那么如果全部可以贿赂呢?我们想,一个强联通分量里面随便贿赂一个点,其他的全部都会被贿赂 那么我们是不是只在需要在进行tarjan的时候进行比较,求出最小值即可

然而 

如果一个强联通分量指向另一个强联通分量,我们就可以用指向另一个的强联通分量里的最小值就可以了

有同学问:如果被指向的强联通分量里面有一个比指向的最小值还小的值,是不是可以用呢?

答案是不可以的 如果选择了指向的强联通分量,我们的花费是x,此时因为他指向另一个强联通分量,所以另一个不需要花钱,所以我们只需要统计入度为0的强联通分量,并且累加答案就可以了

注意:在进行tarjan的时候while(stack[top]! = u)前面后面都要有一个更新答案 因为有2中种特殊情况:u在栈顶和栈尾,当然你也可以不这么写,直接将top+1即可while(stack[top + 1] != u)

Code

 

#include <bits/stdc++.h>
const int INF = 1e9 + 10;
using namespace std;
int n, p, r, num, top, col, sh;
int mon[3010], coin[3010], head[10010], dfn[3010];
int st[3010], co[3010], low[3010], si[3010], vis[3010];
int ans[3010], ru[3010];
struct emmm {
    int next, to;
}e[10010];
void tarjan(int u) {
    st[++top] = u;
    dfn[u] = low[u] = ++sh;
    vis[u] = 1;
    for (int i = head[u]; i; i = e[i].next) {
        int v = e[i].to;
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (!co[v]) 
            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        co[u] = ++col;
        si[col]++;
        ans[col] = min(ans[col], mon[st[top]]);
        while (st[top] != u) {
            si[col]++;
            co[st[top]] = col;
            vis[st[top]] = 0;
            ans[col] = min(ans[col], mon[st[top]]);
            top--;
        }
        ans[col] = min(ans[col], mon[st[top]]);
        top--;
    }
    return ;
} 
void add(int from, int to) {
    e[++num].next = head[from];
    e[num].to = to;
    head[from] = num;
}
int main()
{
    ios::sync_with_stdio(false);
       cin >> n >> p;
       for (int i = 1;i <= n; i++)
           mon[i] = INF;
       for (int i = 1;i <= n; i++)
           ans[i] = INF - 110;
       for (int i = 1;i <= p; i++){
           int u, m;
           cin >> u >> m;
           mon[u] = m;
       }
       cin >> r;
       for (int i = 1;i <= r; i++) {
           int a, b;
           cin >> a >> b;
           add(a, b);
       }
       for (int i = 1;i <= n; i++)
           if (!dfn[i] && mon[i] != INF) 
               tarjan(i);
       for (int i = 1;i <= n; i++)
           if (!dfn[i]) {
               cout << "NO" <<endl << i << endl;
               return 0;
           }
       for (int i = 1;i <= n; i++)
           for (int j = head[i]; j; j = e[j].next) 
               if (co[i] != co[e[j].to]) 
                   ru[co[e[j].to]]++;
       int anss = 0;
       for (int i = 1;i <= col; i++)
           if (!ru[i])
               anss+=ans[i];
       cout << "YES" << endl << anss << endl;
    return 0;
}
AC Code

 

标签:洛谷,int,3010,top,st,间谍,low,P1262,col
来源: https://www.cnblogs.com/-sheldon/p/11403635.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有