zoukankan      html  css  js  c++  java
  • 题解 P1262 【间谍网络】

    由于外国间谍的大量渗入,国家安全正处于高度的危机之中。如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B。有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报。所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子。因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报。

    我们的反间谍机关提供了一份资料,包括所有已知的受贿的间谍,以及他们愿意收受的具体数额。同时我们还知道哪些间谍手中具体掌握了哪些间谍的资料。假设总共有n个间谍(n不超过3000),每个间谍分别用1到3000的整数来标识。

    请根据这份资料,判断我们是否有可能控制全部的间谍,如果可以,求出我们所需要支付的最少资金。否则,输出不能被控制的一个间谍。

    前置知识:

    分析

    会了强联通分量以后呢,我们可以开始写这道题了。首先这道题不是一个 DAGDAG 我们应该先缩点,把这个图变成一个 DAGDAG

    变成 DAGDAG 就好了,我们就可以记录每个点的入度,答案即为所有入度为 00 的点的值的和(值就是这个点内的所有人被收买的数额中的最小值(不会被收买钱数为 infinf))。

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    template<typename T>inline void read(T &FF){
    	T RR=1;FF=0;char CH=getchar();
    	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
    	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
    	FF*=RR;
    }
    template<typename T>inline void write(T x){
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar('0'+x%10);
    }
    const int MAXN=1e6+10,MAXM=1e6+10;
    int s[MAXN],stop,dfn[MAXN],low[MAXN],scccnt,sccnum[MAXN],dfscnt,tot,he[MAXN],ne[MAXM<<1],ed[MAXM<<1],n,x,y,de[MAXN],ans,m,k,dis[MAXN],num[MAXN],sum[MAXN];
    void add(int x,int y){
    	ed[++tot]=y;
    	ne[tot]=he[x];
    	he[x]=tot;
    }
    inline void tarjan(int now){
    	dfn[now] = low[now] = ++dfscnt;
    	s[stop++] = now;
    	for (int i=he[now];i;i=ne[i]){
    		if(!dfn[ed[i]]){
    			tarjan(ed[i]);
    			low[now] = min(low[now], low[ed[i]]);
    		}else if(!sccnum[ed[i]]) {
    			low[now] = min(low[now], dfn[ed[i]]);
    		}
    	}
    	if(dfn[now]==low[now]){
    		scccnt++;
    		do{
    			sccnum[s[--stop]]=scccnt;
    			sum[scccnt]=min(sum[scccnt],dis[s[stop]]);//取min
    		}while(s[stop]!=now);
    	}
    }//强联通分量
    signed main(){
    	memset(sum,127,sizeof(sum));//赋上无穷大
    	memset(dis,127,sizeof(dis));//赋上无穷大
    	read(n);read(k);
    	for(int i=1;i<=k;i++)read(num[i]),read(dis[num[i]]);
    	read(m);
    	for(int i=1;i<=m;i++){
    		read(x);read(y);
    		add(x,y);
    	}
    	for(int i=1;i<=k;i++)
    		if(!dfn[num[i]])tarjan(num[i]);
    	for(int i=1;i<=n;i++)
    		if(!dfn[i])return cout<<"NO
    "<<i,0;//可以被收买的点中不知道这个点的消息,即为不可以控制所有间谍
    	for(int i=1;i<=n;i++)
    		for(int j=he[i];j;j=ne[j])
    			if(sccnum[i]!=sccnum[ed[j]])de[sccnum[ed[j]]]++;
    	for(int i=1;i<=scccnt;i++)
    		if(!de[i])ans+=sum[i];
    	cout<<"YES
    "<<ans;
    	return 0;
    }
    
  • 相关阅读:
    MongoDB repair on Ubuntu
    java后台图形相关代码,weblogic报错
    weblogic配置达梦数据源
    详解JavaScript中的this
    web app指南之构建html5离线应用
    android中的跨进程通信的实现(一)——远程调用过程和aidl
    android应用开发全程实录出版
    android窗口管理框架解析
    BizTalk调用SAP系统RFC含多个参数以及DateTime类型参数
    plsql连接64位oracle在windows 764下连接设置方法
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816949.html
Copyright © 2011-2022 走看看