去年省赛的第四题,也算是一道压轴题了,,刚开始没太读懂题意,用了并查集 乱搞。。 最后想想应该是用强连通缩点。

其实昨天晚上就已经写好了代码, 不过在南工上交一直 TLE ,很纳闷, 感觉和以往写的强连通差不多啊。。

一看再看还是没有找到错误。。

今天和战友们讨论发现有一个地方没有处理好,就是缩点之后的深搜, 对于该商品的最大价值没有处理好。。

改过之后索性仍是TLE 。。  后来找到测试数据,,共有 三组测试实例,,但是无论怎么搞都只有两组输出,

最后很无语的放下了。。吃过饭后再看下,猛然发现edge开小了, 改过之后 就AC了。。内牛满面。。

明明是RE,为啥总是提醒我TLE。。。

思路:先用强连通缩点 , 之后再建新图,从起点深搜一遍就ok了。

贴下代码:

# include<stdio.h>
# include<string.h>
# include<time.h>
# define N 100005
# define M 500005
struct node{
	int from,to,next;
}edge1[M],edge2[M],edge[M];//这个地方刚开始开成大小的N的了
int visit1[N],visit2[N],head1[N],head2[N],max[N],min[N],head[N],visit[N];
int val[N],Belong[N],T[N],n,m,Bcnt,Tcnt,tol1,tol2,MAX,end,start,tol;
void add(int a,int b)
{
	edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];head1[a]=tol1++;
	edge2[tol2].from=b;edge2[tol2].to=a;edge2[tol2].next=head2[b];head2[b]=tol2++;
}
void add1(int a,int b)
{
	edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++;
}
void dfs1(int x)
{
	int i;
	visit1[x]=1;
	for(i=head1[x];i!=-1;i=edge1[i].next)
	{
		if(visit1[edge1[i].to]==0) dfs1(edge1[i].to);
	}
	T[Tcnt++]=x;
}
void dfs2(int x)
{
	int i;
	visit2[x]=1;
	Belong[x]=Bcnt;
	if(val[x]>max[Bcnt]) max[Bcnt]=val[x];
	if(val[x]<min[Bcnt]) min[Bcnt]=val[x];
	for(i=head2[x];i!=-1;i=edge2[i].next)
		if(visit2[edge2[i].to]==0) dfs2(edge2[i].to);	
}
void dfs(int x,int tmax,int min1)
{
	int i,index;
	if(min1>min[x]) min1=min[x];
	if(max[x]-min1> tmax) tmax=max[x]-min1;
	if(x==end) 
	{
		if(tmax>MAX) MAX = tmax;
		return;
	} 
	for(i=head[x];i!=-1;i=edge[i].next)
	{
		index=edge[i].to;
		if(visit[index]==0) 
		{
			visit[index]=1;
			dfs(index,tmax,min1);
			visit[index]=0;
		}
	}
}
int main()
{
	int i,a,b,z,x,y;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(i=1;i<=n;i++)
		{
			scanf("%d",&val[i]);
			visit1[i]=visit2[i]=0;
			head[i]=head1[i]=head2[i]=-1;
		}
		head1[0]=head[0]=head2[0]=-1;
		visit1[0]=visit2[0]=0;
		tol=tol1=tol2=0;
		Bcnt=Tcnt=0;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&a,&b,&z);
			add(a,b);
			if(z==2) add(b,a);
		}
		for(i=1;i<=n;i++)
			if(visit1[i]==0) dfs1(i);
			for(i=Tcnt-1;i>=0;i--)
			{
				if(visit2[T[i]]==0)
				{
					max[Bcnt]=-1;
					min[Bcnt]=105;
					dfs2(T[i]);
					Bcnt++;
				}
			}

			for(i=0;i<tol1;i++)
			{
				x=Belong[edge1[i].from];
				y=Belong[edge1[i].to];
				if(x!=y)
				{
					add1(x,y);
				}
			}
			/*建图会建好多的重边,严重的浪费,这个还没有想到怎么优化*/
			for(i=0;i<=Bcnt;i++)
				visit[i]=0;
			
			MAX=0;
			start=Belong[1];
			end=Belong[n];
			dfs(start,0,min[start]);
			printf("%d\n",MAX);
	}
	return 0;
}
posted on 2011-05-11 21:03  奋斗青春  阅读(226)  评论(0编辑  收藏  举报