zoukankan      html  css  js  c++  java
  • Luogu P1262 间谍网络

    Description:

    由于外国间谍的大量渗入,国家安全正处于高度的危机之中。如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B。有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报。所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子。因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报。
    我们的反间谍机关提供了一份资料,包括所有已知的受贿的间谍,以及他们愿意收受的具体数额。同时我们还知道哪些间谍手中具体掌握了哪些间谍的资料。假设总共有n个间谍(n不超过3000),每个间谍分别用1到3000的整数来标识。
    请根据这份资料,判断我们是否有可能控制全部的间谍,如果可以,求出我们所需要支付的最少资金。否则,输出不能被控制的一个间谍。

    Analysis:

    显然强连通分量里的点都可以互相控制。
    tarjan缩点建新图,存下每个强连通里的点的最小值,同时该强连通分量的费用等于所有点的费用和。
    难得做一道题这么顺利就AC了

    Code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define YES 1
    #define NO 0
    using namespace std;
    const int N = 3010,M = 8010,INF = 0x3f3f3f3f;
    struct edge{
    	int u,v,next;
    }e[M],G[M];
    int head[N],dfn[N],low[N],scc[N],pr[N],ind[N],num_dfs,num_scc,num_edge1,num_edge2,n,p,m;
    int st[N],top;
    int Ins[N],cost[N],ans,minimum;
    void tarjan(int u)
    {
    	dfn[u] = low[u] = ++num_dfs;
    	st[++top] = u;
    	for(int i = head[u];i;i = e[i].next)
    	{
    		int v = e[i].v;
    		if(!dfn[v])
    		{
    			tarjan(v);
    			low[u] = min(low[u],low[v]);
    		}else if(!scc[v])
    		{
    			low[u] = min(low[u],dfn[v]);
    		}
    	}
    	if(low[u] == dfn[u])
    	{
    		scc[u] = ++num_scc;
    		Ins[num_scc] = u;
    		if(pr[u]) cost[num_scc] = min(cost[num_scc],pr[u]);
    		while(st[top] != u)
    		{
    			scc[st[top]] = num_scc;
    			Ins[num_scc] = min(st[top],Ins[num_scc]);
    			if(pr[st[top]]) cost[num_scc] = min(cost[num_scc],pr[st[top]]);
    			--top;
    		}
    		--top;
    	}
    }
    void add(edge E[],int a,int b,int &num)
    {
    	E[++num].next = head[a];
    	E[num].u = a;
    	E[num].v = b;
    	head[a] = num;
    }
    void solve()
    {
    	minimum = INF;
    	memset(cost,0x3f,sizeof(cost));
    	for(int i = 1;i <= n;++i)
    	{
    		if(!dfn[i]) tarjan(i);
    	}
    	memset(head,0,sizeof(head));
    	for(int i = 1;i <= m;++i)
    	{
    		int u = e[i].u,v = e[i].v;
    		if(scc[u] != scc[v])
    		{
    			add(G,scc[u],scc[v],num_edge2);
    			++ind[scc[v]];	
    		}
    	}
    	int flag = YES;
    	for(int i = 1;i <= num_scc;++i)
    	{
    		if(ind[i] == 0)
    		{
    			if(cost[i] < INF) ans += cost[i];
    			else{
    				flag = NO;
    				minimum = min(minimum,Ins[i]);
    			}
    		}
    	}
    	if(flag == YES) printf("YES
    %d",ans);
    	else printf("NO
    %d",minimum);
    }
    int main()
    {
    	scanf("%d%d",&n,&p);
    	for(int i = 1;i <= p;++i)
    	{
    		int k;
    		scanf("%d",&k);
    		scanf("%d",&pr[k]);
    	}
    	scanf("%d",&m);
    	for(int i = 1;i <= m;++i)
    	{
    		int a,b;
    		scanf("%d%d",&a,&b);
    		add(e,a,b,num_edge1);
    	}
    	solve();
    	return 0;
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    ecplise 导出maven项目依赖的jar
    vue.js 中组件的使用
    爬虫:python采集豆瓣影评信息并进行数据分析
    Python爬取前程无忧十万条招聘数据
    爬虫:新浪微博爬虫的最简单办法
    爬虫:利用python完成百度贴吧数据采集
    基于SSM框架的新生报到可视化系统
    爬虫:利用selenium采集某某环境网站的空气质量数据
    基于flask框架的高校舆情分析系统
    基于flask的城市空气质量分析系统
  • 原文地址:https://www.cnblogs.com/Zforw/p/10908653.html
Copyright © 2011-2022 走看看