题意:给出n个点的无向图, 问你每个点的“鸽子值”(就是把这个点删除之后原图变成几个连通分块)
这题有两种解法
1、直接判断哪个点是割点 , 但这要加一点 , 标记一个点是否是割点时变成 , iscnt[u] += 1;
但要注意一点 , 除开根节点, 所有点在完成找割点之后, 都要加1(因为还有包括图本身)
2、求出这个图的所以双连通分量 , 然后再看每个点在几个双连通分量中 , 这就是其“鸽子值”
代码1:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 20000 ;
vectorgrap[MAXN];
int pre[MAXN] , low[MAXN] ;
int is_cnt[MAXN] , dfs_clock ;
int n , m ;
bool cmp(int i , int j)
{
if(is_cnt[i] == is_cnt[j])
return i
return is_cnt[i]>is_cnt[j];
}
void init()
{
for(int i = 0 ; i <= n; i++)
grap[i].clear();
memset(pre , 0 , sizeof(pre));
memset(is_cnt , 0 , sizeof(is_cnt));
dfs_clock = 0;
}
int dfs(int u , int fa)
{
int lowu = pre[u] = ++dfs_clock;
int child = 0;
for(int i = 0 ; i < grap[u].size() ; i++)
{
int v = grap[u][i] ;
if(!pre[v])
{
child++;
int lowv = dfs(v , u);
lowu = lowu>lowv?lowv:lowu;
if(lowv >= pre[u])
is_cnt[u] += 1;
}
else if(pre[v] < pre[u] && v != fa)
{
lowu = lowu
这题有两种解法
1、直接判断哪个点是割点 , 但这要加一点 , 标记一个点是否是割点时变成 , iscnt[u] += 1;
2、求出这个图的所以双连通分量 , 然后再看每个点在几个双连通分量中 , 这就是其“鸽子值”
代码1:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 20000 ;
vectorgrap[MAXN];
int pre[MAXN] , low[MAXN] ;
int is_cnt[MAXN] , dfs_clock ;
int n , m ;
bool cmp(int i , int j)
{
}
void init()
{
}
int dfs(int u , int fa)
{
}
}
if(fa < 0)
is_cnt[u] -= 1;
low[u] = lowu;
return lowu;
}
int main()
{
while(scanf("%d %d" , &n , &m) != EOF)
{
if(n == 0&& m==0) break;
init();
int i , x , y ;
for( ; ;)
{
scanf("%d %d" , &x , &y);
if(x ==-1 && y==-1) break;
grap[x].push_back(y);
grap[y].push_back(x);
}
// dfs(0 , -1);
y = 0;
int bz[MAXN];
for(i = 0 ; i < n; i++)
{
if(!pre[i])
{
dfs(0 , -1);
y += 1;
}
bz[i] = i;
}
sort(bz , bz+n , cmp);
for(i = 0 ; i < m; i++)
{
x = bz[i];
printf("%d %d\n" , x , is_cnt[x]+y);
}
cout<<endl;
}
return 0;
}
代码2:
#include
#include
#include
#include
#include
#include
using namespace std;
struct edge
{
int u , v;
edge(int u , int v)
{
this->u = u;
this->v = v;
}
};
const int MAXN = 10000+5;
int pre[MAXN] , iscut[MAXN] , bccno[MAXN] , dfs_clock , bcc_cnt;
vectorgrap[MAXN] , bcc[MAXN];
int n , m ;
int gx[MAXN] , bz[MAXN];
stacks;
bool cmp(int i , int j)
{
if(gx[i] == gx[j]) return i
return gx[i]>gx[j];
}
void init()
{
for(int i = 0 ; i <= n; i++)
grap[i].clear();
memset(pre , 0 , sizeof(pre));
memset(iscut , 0 , sizeof(iscut));
memset(bccno , 0 , sizeof(bccno));
dfs_clock = bcc_cnt = 0;
}
int dfs(int u , int fa)
{
int lowu = pre[u] = ++dfs_clock;
int child = 0;
for(int i = 0 ; i < grap[u].size() ; i++)
{
int v = grap[u][i];
edge e = (edge){u , v};
if(!pre[v])
{
child++;
s.push(e);
int lowv = dfs(v , u);
lowu = lowu
if(lowv >= pre[u])
{
iscut[u] = 1;
bcc_cnt++;
bcc[bcc_cnt].clear();
for( ; ; )
{
edge x = s.top() ; s.pop();
if(bccno[x.u] != bcc_cnt) {bcc[bcc_cnt].push_back(x.u) ; bccno[x.u] = bcc_cnt ;}
if(bccno[x.v] != bcc_cnt) {bcc[bcc_cnt].push_back(x.v) ; bccno[x.v] = bcc_cnt ;}
if(x.u == u && x.v == v) break;
}
}
}
else if(pre[v] < pre[u] && v != fa)
{
s.push(e);
lowu = lowu
}
}
if(fa < 0 && child == 1) iscut[u] = 0;
return lowu;
}
int main()
{
while(scanf("%d %d" , &n , &m) != EOF)
{
if(n == 0 && m == 0) break;
init();
int i , x , y;
for( ; ; )
{
scanf("%d %d" , &x , &y);
if(x == -1 && y == -1) break;
grap[x].push_back(y);
grap[y].push_back(x);
}
for(i = 0 ; i < n; i++)
{
if(!pre[i])
dfs(i , -1);
bz[i] = i;
}
memset(gx , 0 , sizeof(gx));
for(i = 1; i <= bcc_cnt ; i++)
{
for(int j = 0 ; j < bcc[i].size() ; j++)
{
int v = bcc[i][j];
gx[v] += 1;
}
}
sort(bz , bz+n , cmp);
for(i = 0 ; i < m; i++)
{
x = bz[i];
printf("%d %d\n" , x , gx[x]);
}
cout<<endl;
}
return 0;
}