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

BZOJ 1093 ZJOI2007 最大半连通子图 Tarjan+动态规划

时间:2015-01-19 21:11:11      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:bzoj   bzoj1093   tarjan   动态规划   

题目大意:定义半连通子图为一个诱导子图,其中任意两点(x,y)中x可到达y或y可到达x,求最大半连通子图的大小以及方案数

不就是个缩点之后拓扑序DP求最长链么 这题意逗不逗233333

注意缩点后连边不要连重复了 判重边那里我用了set。。。

#include <set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
int n,m,p;
int ans1,ans2;
namespace New_Graph{
	struct abcd{
		int to,next;
	}table[1001001];
	int head[M],tot;
	int cnt,size[M];
	int len[M],ways[M];
	void Add(int x,int y)
	{
		table[++tot].to=y;
		table[tot].next=head[x];
		head[x]=tot;
	}
	void Topology_DP()
	{
		int i,x;
		for(x=cnt;x;x--)
		{
			len[x]=size[x];ways[x]=1;
			for(i=head[x];i;i=table[i].next)
			{
				if(len[table[i].to]+size[x]>len[x])
					len[x]=len[table[i].to]+size[x],ways[x]=0;
				if(len[table[i].to]+size[x]==len[x])
					(ways[x]+=ways[table[i].to])%=p;
			}
			if(len[x]>ans1)
				ans1=len[x],ans2=0;
			if(len[x]==ans1)
				(ans2+=ways[x])%=p;
		}
	}
}
namespace Old_Graph{
	struct abcd{
		int to,next;
	}table[1001001];
	int head[M],tot;
	bool v[M];
	int belong[M];
	void Add(int x,int y)
	{
		table[++tot].to=y;
		table[tot].next=head[x];
		head[x]=tot;
	}
	void Tarjan(int x)
	{
		static int dpt[M],low[M],T;
		static int stack[M],top;
		int i;
		low[x]=dpt[x]=++T;
		stack[++top]=x;
		for(i=head[x];i;i=table[i].next)
		{
			if(v[table[i].to])
				continue;
			if(dpt[table[i].to])
				low[x]=min(low[x],dpt[table[i].to]);
			else
			{
				Tarjan(table[i].to);
				low[x]=min(low[x],low[table[i].to]);
			}
		}
		if(dpt[x]==low[x])
		{
			using namespace New_Graph;
			int t;cnt++;
			do{
				t=stack[top--];
				v[t]=1;belong[t]=cnt;
				size[cnt]++;
			}while(t!=x);
		}
	}
}
int main()
{
	using namespace Old_Graph;
	int i,x,y;
	cin>>n>>m>>p;
	for(i=1;i<=m;i++)
		scanf("%d%d",&x,&y),Add(x,y);
	for(i=1;i<=n;i++)
		if(!v[i])
			Tarjan(i);
	static set<int> mark[M];
	for(x=1;x<=n;x++)
		for(i=head[x];i;i=table[i].next)
			if(belong[table[i].to]!=belong[x])
				if(mark[belong[table[i].to]].find(belong[x])==mark[belong[table[i].to]].end())
				{
					New_Graph::Add(belong[table[i].to],belong[x]);
					mark[belong[table[i].to]].insert(belong[x]);
				}
	New_Graph::Topology_DP();
	cout<<ans1<<endl<<ans2<<endl;
	return 0;
}


BZOJ 1093 ZJOI2007 最大半连通子图 Tarjan+动态规划

标签:bzoj   bzoj1093   tarjan   动态规划   

原文地址:http://blog.csdn.net/popoqqq/article/details/42876197

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