Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
WA的让人崩溃,请大家帮忙,多谢!思路如下: 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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator