hdu3072 Intelligence System (Tarjan)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3072


题解:一个强连通图里 inform,cost忽略,求强连通图之间的最小cost.


#include <stdio.h>      
#include <string.h>
#define INF 0x3f3f3f3f
#define MAXN 50001   

struct node      
{      
	int to,next,val;      
}edge[MAXN<<1];  

int belong[MAXN],cost[MAXN];      
int head[MAXN],instack[MAXN],low[MAXN],dfn[MAXN];        
int stack[MAXN],tot,Dindex,top,Bcnt;  

void Init()        
{//初始化 
	int i;
	tot=0,top=0,Dindex=0,Bcnt=0;        
	memset(head,-1,sizeof(head));        
	memset(instack,0,sizeof(instack));        
	memset(dfn,0,sizeof(dfn));        
	memset(low,0,sizeof(low));       
	memset(belong,0,sizeof(belong));
	memset(cost,INF,sizeof(cost));
}  

int Scan()                
{                
	char ch;                
	int ret=0;                
	while((ch=getchar())<'0'||ch>'9');                
	while(ch>='0'&&ch<='9')                
	{                
		ret=ret*10+(ch-'0');                
		ch=getchar();                
	}                
	return ret;                
}  

void addEdge(int from,int to,int w)        
{      
	edge[tot].to=to;
	edge[tot].val=w;
	edge[tot].next=head[from];        
	head[from]=tot++;        
} 

void Tarjan(int x)      
{      
	int i,u,v;      
	dfn[x]=low[x]=++Dindex;//时间戳      
	stack[top++]=x;      
	instack[x]=1;      
	for(i=head[x];i!=-1;i=edge[i].next)      
	{      
		u=edge[i].to;      
		if(!dfn[u])      
		{      
			Tarjan(u);      
			low[x]=low[x]>low[u]?low[u]:low[x];      
		}      
		else if(instack[u]&&low[x]>dfn[u])      
			low[x]=dfn[u];      
	}      
	if(low[x]==dfn[x])      
	{ 
		Bcnt++;      
		do       
		{      
			v=stack[--top];      
			instack[v]=0;   
			belong[v]=Bcnt;      
		} while (v!=x);
	}      
} 

int main()
{
	int n,m,i,j,x,y,w,ans;
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		Init();
		while(m--)
		{
			x=Scan();
			y=Scan();
			w=Scan();
			x++;
			y++;
			addEdge(x,y,w);
		}
		for(i=1;i<=n;++i)
		{
			if(!dfn[i])
				Tarjan(i);
		}
		for(i=1;i<=n;++i)
		{
			for(j=head[i];j!=-1;j=edge[j].next)
			{
				x=edge[j].to;
				if(belong[i]!=belong[x])
				{
					if(cost[belong[x]]>edge[j].val)
						cost[belong[x]]=edge[j].val;
				}
			}
		}
		ans=0;
		for(i=1;i<=Bcnt;++i)
		{
			if(cost[i]!=INF)
				ans+=cost[i];
		}
		printf("%d\n",ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值