| ||||||||||
| 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