ICode9

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

P1262 间谍网络

2020-03-27 10:55:09  阅读:257  来源: 互联网

标签:temp int 网络 ++ 间谍 maxn low P1262 now


题目传送门

描述:\(给你一个有向图,其中某些点是可以买的,如果你买了一个点,\)

\(你可以到达这个点指向的点,指向的这个点又能到它指向的点......(直到走不通),我们要选择一些点买,使图联通且代价最小!\)

算法:tarjan缩点

思考过程

选择哪一些点,能使图联通且代价最小呢?

我们试着想一下,如果一个点被其他点指向,那我们最好选那个点

如果那个点也被其他点指向,我们一直追溯过去,入度为0的点必须要选了

但是如果存在环,那么没有点入度为0,这个时候就需要缩点,变成我们上面的那种情况

缩点后环的代价就是环中点的最小代价

问题又来了,如果环中没有点可以买怎么办??

所以tarjan的时候只对那些可以买的点进行找环

最后扫一遍,如果有点的dfn为0,说明没有遍历,即它是孤立的,没办法买到的,输出NO~

#include <bits/stdc++.h>
using namespace std;
const int maxn=16009;
const int inf=999999999;
int n,m,q;
struct p{
	int to,nxt,w;
}d[maxn];int head[maxn],cnt=1;
void add(int u,int v,int w){
	d[cnt].to=v,d[cnt].w=w,d[cnt].nxt=head[u],head[u]=cnt++;
}
int indug[maxn],monney[maxn],sumn[maxn];
int low[maxn],dfn[maxn],stac[maxn],vis[maxn],top,id,sd[maxn],fen;
void tarjan(int now)
{
	dfn[now]=low[now]=++id;
	stac[++top]=now,vis[now]=1;
	for(int i=head[now];i;i=d[i].nxt)
	{
		int v=d[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[now]=min(low[now],low[v]);
		}
		else if(vis[v])	low[now]=min(low[now],low[v]);
	}
	if(dfn[now]==low[now])
	{
		fen++;int temp;
		while(temp=stac[top--])
		{
			vis[temp]=0;
			sd[temp]=fen;
			sumn[fen]=min(sumn[fen],monney[temp]);
			if(temp==now)	break;
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)	monney[i]=sumn[i]=inf;
	for(int i=1;i<=m;i++)
	{
		int l,r;cin>>l>>r;
		indug[l]++;monney[l]=r;
	}
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		int l,r;cin>>l>>r;
		add(l,r,0);indug[r]++;
	}
	for(int i=1;i<=n;i++)
		if(indug[i]==0)
		{
			cout<<"NO"<<endl<<i;
			return 0;
		}
	for(int i=1;i<=n;i++)//开始缩点
	if(!dfn[i]&&monney[i]!=-1)	tarjan(i);
	memset(indug,0,sizeof(indug));
	for(int i=1;i<=n;i++)
		for(int j=head[i];j;j=d[j].nxt)
		{
			int v=d[j].to;
			if(sd[i]==sd[v])	continue;
			indug[sd[v]]++;
		}
	int ans=0;
	for(int i=1;i<=fen;i++)
	if(!indug[i])	ans+=sumn[i];
	cout<<"YES"<<endl<<ans;
	return 0;
}

标签:temp,int,网络,++,间谍,maxn,low,P1262,now
来源: https://www.cnblogs.com/iss-ue/p/12579837.html

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

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

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

ICode9版权所有