CSUOJ 1208-排队

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1208

亏我还想用并查集去做,这道题用数组模拟链表就行,数组下标为编号,一个一个接下去就行,

在接的同时计数。这题有点恶心的是必须把数组开到101000以上,要不就会RE,这也是考查

的一个方面吧!

#include<iostream>
#include<string.h>
using namespace std;
const int N = 101005;
int next[N];

int main()
{
int n, m;
int a, b;
while( cin >> n >> m)
{
memset( next, 0, sizeof(next) );
for( int i = 1; i <= m; i ++)
{
cin >> a >> b;
next[a] = b;
}
int min = 1000001, k;
for( int i = 1; i <= n; i ++)
{
int cnt = 0;
for( int j = next[i]; j; j = next[j])
cnt ++;
if( cnt < min) {
min = cnt;
k = i;
}
}
cout << k << endl;
}
return 0;
}

 下面是并查集:

#include<stdio.h>
#define N 101005

int p[N], cnt[N], n, m;

int find_set( int x)
{
return p[x] == x ? x : ( p[x] = find_set( p[x]) );
}

void union_set( int x, int y)
{
x = find_set( x);
y = find_set( y);
if( x == y) return;
else if( x > y) {
p[x] = y;
cnt[y] += cnt[x];
}
else {
p[y] = x;
cnt[x] += cnt[y];
}
}

int main()
{
int a, b;
while( scanf( "%d%d", &n, &m) == 2)
{
int i;
for( i = 1; i <= n; i ++)
{
p[i] = i;
cnt[i] = 0;
}
for( ; i <= n + m; i ++)
{
p[i] = i;
cnt[i] = 1;
}
while( m --)
{
scanf( "%d%d", &a, &b);
union_set( a, b);
}

int min = cnt[1], k = 1;
for( i = 2; i <= n; i ++)
{
if( cnt[i] < min) {
min = cnt[i];
k = i;
}
}
printf( "%d\n", k);
}
return 0;
}

 

你可能感兴趣的:(OJ)