Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

WA的让人崩溃,请大家帮忙,多谢!

Posted by GaryLiang at 2010-02-22 16:36:51 on Problem 2186
思路如下:
1:假设a和b都是最受欢迎的cow,那么,a欢迎b,而且b欢迎a,于是,a和b是属于同一个连通分量内的点,所有,问题的解集构成一个强连通分量。
2:如果某个强连通分量内的点a到强连通分量外的点b有通路,因为b和a不是同一个强连通分量内的点,所以b到a一定没有通路,那么a不被b欢迎,于是a所在的连通分量一定不是解集的那个连通分量。
3:如果存在两个独立的强连通分量a和b,那么a内的点和b内的点一定不能互相到达,那么,无论是a还是b都不是解集的那个连通分量,问题保证无解。
4:如果图非连通,那么,至少存在两个独立的连通分量,问题一定无解。 

连通分量是根据算法导论的算法写的,两次DFS,第一次在原图上进行,第二次在原图的转置上进行,根据f[u]的降序排列依次遍历
con[][]这个数组中的每一行存储每一个连通分量内的节点

代码如下: 



#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

#define MAXN 10010
#define MAXE 50010

struct Edge{
	
	int to;
	int next;
};
 Edge g[MAXN+MAXE];
 Edge gt[MAXN+MAXE];

class F{

public:
	int u;
	int t;
};

bool operator <(const F &lf ,const F &rf){
	return !(lf.t<rf.t);
}

F f[MAXN];
int con[MAXN][MAXN];
int col[MAXN];
int base1,base2;

int m,n;
int time,inx1,inx2;

void DFS_Vis(int flag,int u, Edge gg[MAXN+MAXE]){

	col[u]=1;
	++time;
	int nt;
	nt=gg[u].next;
	int to;
	while(nt!=0){
		to=gg[nt].to;
		if(col[to]==0){
			if(flag==2){
				con[inx1][inx2]=to;
				++inx2;
			}
			DFS_Vis(flag,to,gg);
		}
		nt=gg[nt].next;
	}
	col[u]=2;
	if(flag==1){
		f[u].u=u;
		++time;
		f[u].t=time;
	}
}

void DFS(int flag, Edge gg[MAXN+MAXE]){
	
	memset(col,0,sizeof(col));

	if(flag==1){
		memset(f,0,sizeof(f));
	}
	time=0;
	inx1=0;
	inx2=0;

	if(flag==1){
		for(int i=1;i<=n;i++){
			if(col[i]==0)
				DFS_Vis(flag,i,gg);
		}
	}
	else if(flag==2){
		for(int i=1;i<=n;i++){
			if(col[f[i].u]==0){
				inx2=0;
				con[inx1][inx2]=f[i].u;
				++inx2;
				DFS_Vis(flag,f[i].u,gg);
				++inx1;
			}
		}
	}


}


int main(){
	
	memset(g,0,sizeof(g));
	memset(gt,0,sizeof(gt));
	scanf("%d%d",&n,&m);

	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			con[i][j]=0;
	
	base1=base2=MAXN+1;
	int x1,x2;
	for(int i=0;i<m;i++){
	
		scanf("%d%d",&x1,&x2);
		g[base1].next=g[x1].next;
		g[base1].to=x2;
		g[x1].next=base1;
		++base1;

		gt[base2].next=gt[x2].next;
		gt[base2].to=x1;
		gt[x2].next=base2;
		++base2;
	}
	
	DFS(1,g);
	sort(f+1,f+n+1);
	DFS(2,gt);
	if(inx1==1){
		printf("%d\n",n);
		return 0;
	}
	int rt;
	bool flag1,flag2,flag3;
	flag1=flag2=flag3=false;
	for(int i=0;i<inx1;i++){
		flag1=false;
		inx2=0;
		int tp=con[i][inx2++];
		while(tp!=0){
			if(g[tp].next!=0){
				flag1=true;
				break;
			}
			tp=con[i][inx2++];
		}
		if(!flag1){
			if(!flag2){
				rt=inx2-1;
				flag2=true;
			}
			else {
				printf("%d\n",0);
				return 0;
			}
		}

	}
	if(!flag1){
		printf("%d\n",rt);
	}
	else {
		printf("%d\n",0);
	}

}









Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator