码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 11770 Lighting Away

时间:2014-07-26 00:08:36      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   使用   os   io   width   2014   

RunID

User

Problem

Result

Memory

Time

Language

Length

Submit Time

2482977

zhyfzy

J

Accepted

0 KB

138 ms

C++ 4.8.2

2322 B

2014-07-24 15:18:54

【题目大意】

一个有向图,每对一个结点操作,就可以触发连锁反应,使得该结点及它直接或间接指向的点均获得标记,问至少需要操作多少个结点使得所有结点获得标记

【题解】

缩点+DFS

首先能想到入度为0的点一定需要操作,但是操作完所有入度为0的点不一定使所有结点获得标记,比如存在环的情况,因此,我们需要先缩点,缩点使用Tarjan算法,详见代码,缩点之后直接统计入度为0的点有多少个即可。

代码采用链式向前星的存储结构

【代码】

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<stack>
#define P 20000
#define E 200000
using namespace std;
int i,j,k,n,T,ans,K,m,x,y,indexs,nn,mm;
int ru[P],head[P],head2[P],dfn[P],low[P],instack[P],belong[P];
bool b[E];
stack <int> tar;
 
struct node
{
	int from;
	int to;
	int next;
}map[E],map2[E];

void addedge(int num,int x,int y)
{
	map[num].from=x;
	map[num].to=y;
	map[num].next=head[x];
	head[x]=num;
}

void addedge2(int num,int x,int y)
{
	//printf("NewEdge %d %d\n",x,y); 
	
	ru[y]++;
	map2[num].from=x;
	map2[num].to=y;
	map2[num].next=head2[x];
	head2[x]=num;
}


void dfs(int p)
{
	for (int i=head2[p];i!=-1;i=map2[i].next)
	{
		if (!b[map2[i].to])
		{
			b[map2[i].to]=true;
			dfs(map2[i].to);
		}
	}
}


void tarjan(int k)
{
    int p;
    tar.push(k);
    instack[k]=1;
    dfn[k]=low[k]=++indexs;
    for(int j=head[k];j!=-1;j=map[j].next)
    {
        p=map[j].to;
        if (instack[p]) 
		{
			low[k]=min(low[k],dfn[p]);
		}
        else 
		if(dfn[p]==-1)
        {
            tarjan(p);
            low[k]=min(low[k],low[p]);
        }
    }
    if(low[k]==dfn[k])
    {
        nn++;
        do
        {
            j=tar.top();
            tar.pop();
            instack[j]=0;
            belong[j]=nn;
        }while(j!=k);
    }
}

void build_new_map()
{
    for(int i=1;i<=m;i++)
    {
        if(belong[map[i].from]==belong[map[i].to]) 
			continue;
        addedge2(++mm,belong[map[i].from],belong[map[i].to]);
    }
}
void build_map()
{
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		addedge(i,x,y);
	}

	memset(dfn,-1,sizeof(dfn));
	memset(low,-1,sizeof(low));
	memset(instack,0,sizeof(instack));
	indexs=0;nn=0;
	
	for (i=1;i<=n;i++) belong[i]=i;
	
	for (i=1;i<=n;i++)
	{
		if (dfn[i]==-1)
			tarjan(i);
	}
	
	build_new_map();
}


int main()
{
	scanf("%d",&T);
	while (++K<=T)
	{
		memset(map,-1,sizeof(map));
		memset(head,-1,sizeof(head));
		memset(map2,-1,sizeof(map2));
		memset(head2,-1,sizeof(head2));
		memset(b,0,sizeof(b));
		memset(ru,0,sizeof(ru));
		ans=0;mm=0;nn=0;
		
		build_map();
		
		for (i=1;i<=nn;i++)
		{
			if (!ru[i])
			{
				ans++;
				b[i]=true;
				dfs(i);
			}
		}
		
		for (i=1;i<=nn;i++)
		{
			if (!b[i])
			{
				ans++;
			 	b[i]=true;
				dfs(i);
			}
		}
		printf("Case %d: %d\n",K,ans);
	}
}

  

UVA 11770 Lighting Away,布布扣,bubuko.com

UVA 11770 Lighting Away

标签:style   blog   http   使用   os   io   width   2014   

原文地址:http://www.cnblogs.com/zhyfzy/p/3868324.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!