POJ3697+BFS+hash存边

时间:2021-10-29 06:22:58
 /*
疾速优化+hash存边
题意:给定一个包含N(1 ≤ N ≤ 10,000)个顶点的无向完全图,图中的顶点从1到N依次标号。从这个图中去掉M(0 ≤ M ≤ 1,000,000)条边,求最后与顶点1联通的顶点的数目
思路(BFS):从顶点1开始不断扩展,广度优先搜索所有的与当前扩展点联通的顶点。开始每次都要判断所有的顶点是否与cur相连,
若相连则push,反之跳过。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<math.h>
using namespace std;
typedef long long int64;
//typedef __int64 int64;
typedef pair<int64,int64> PII;
#define MP(a,b) make_pair((a),(b))
const int maxn = ;
const int maxm = ;
const int smod = ;
const int mod = ;
const int inf = 0x7fffffff;
const double pi=acos(-1.0);
const double eps = 1e-; struct Edge{
int u,v,next;
}edge[ maxm<< ];
int cnt,myhash[ maxm<< ];
queue<int>q;
int vis[ maxn ]; void init(){
cnt = ;
while( !q.empty() )
q.pop();
memset( myhash,-,sizeof( myhash ) );
} void addedge( int a,int b ){
//if( a>b ) swap( a,b );
int tt = (a*smod+b)%mod;
edge[ cnt ].u = a;
edge[ cnt ].v = b;
edge[ cnt ].next = myhash[ tt ];
myhash[ tt ] = cnt++; tt = (b*smod+a)%mod;
edge[ cnt ].u = a;
edge[ cnt ].v = b;
edge[ cnt ].next = myhash[ tt ];
myhash[ tt ] = cnt++; } bool find( int u,int v ){
//if( u>v ) swap( u,v );
int tt = ( u*smod+v )%mod;
for( int i=myhash[tt];i!=-;i=edge[i].next ){
if( edge[ i ].u == u && edge[ i ].v == v ){
return true;
}
}
return false;
} int main(){
int n,m;
int Case = ;
while( scanf("%d%d",&n,&m)==,n+m ){
init();
int x,y;
while( m-- ){
scanf("%d%d",&x,&y);
addedge( x,y );
addedge( y,x );
}
int ans = ;
cnt = ;
q.push( );
for( int i=;i<=n;i++ ){
vis[ cnt++ ] = i;
}
while( !q.empty() ){
int cur = q.front();
q.pop();
int tmp_cnt = ;
for( int i=;i<cnt;i++ ){
if( !find( cur,vis[i] ) ){
ans ++;
q.push( vis[i] );
}
else vis[ tmp_cnt++ ] = vis[i];
}
cnt = tmp_cnt;
}
printf("Case %d: %d\n",Case++,ans);
}
return ;
}