| ||||||||||
| 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 | |||||||||
过了,提供3种方法:1,广搜+二分(1000到3500);2,广搜+hash(200到2000);3,暴力广搜(数组模拟链表,300左右)1,效率不高,优化输入后,还是挺废时间的,第一个版本,代码贴上:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct{ //存储不合适的边
int v, u;
}ary;
ary num[1000007];
typedef struct{//队列
int n, before;
}queue;
queue que[10007];
bool search[10007];
int input()
{
int r=0;
char ch;
while((ch=getchar())>='0'&&ch<='9')
r=r*10+ch-'0';
return r;
}
int n ,m;
bool towsearch(int v, int u){//二分查找
int left = 0, mid, right = m-1;
if(v > u){
int temp = v; v = u; u = temp;
}
while(left <= right){
mid = (left + right) / 2;
if(num[mid].v == v && num[mid].u == u){
return true;
}
else if((num[mid].v == v && num[mid].u < u) || (num[mid].v < v)){
left = mid + 1;
}
else{
right = mid - 1;
}
}
return false;
}
int cmp (const void*a, const void*b){//快速排序
ary* aa = (ary*)a;
ary* bb = (ary*)b;
if(aa->v > bb->v){
return 1;
}
else if(aa->v < bb->v){
return -1;
}
else{
if(aa->u > bb->u)
return 1;
else if(aa->u == bb->u)
return 0;
else
return -1;
}
}
int main(){
int temp = 0;
while(n = input(), m = input(),n , m){
temp++;
memset(search, false, sizeof(search));
int a,b;
for(int i = 0; i < m; ++i){
a = input();
b = input();
//scanf("%d%d", &a, &b);
if(a > b){
int t = a;
a = b;
b = t;
}
num[i].v = a;
num[i].u = b;
}
qsort(num, m, sizeof(num[0]), cmp);
int front, rear;
front = 0;//BFS
rear = 0;
int sum = 0;
que[front].n = 1;
que[front].before = 0;
search[1]=true;
while(front <= rear ){
for(int i = 2; i <= n; ++i){
if(!search[i] && !towsearch(que[front].n,i)){//若点没被visit && 若此边合适即入队,点i即可与1相通
rear++;
que[rear].n = i;
que[rear].before = que[front].n;
search[i] = true;
sum++;
if(m-1 == sum)
break;
}
}
++front;
}
printf("Case %d: %d\n", temp, sum);
}
return 0;
}
第二种,除了优化了输入,还把搜索区间优化了:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define mod 1000117
#define smod 10091
typedef struct{ //存储不合适的边
int x, y;
}ary;
ary num[mod];
int next[mod], hash[mod], point[smod], que[smod];
int endList;
int input()
{
int r=0;
char ch;
while((ch=getchar())>='0'&&ch<='9')
r=r*10+ch-'0';
return r;
}
void insert(int a, int b){
int code = (a * smod + b) % mod;
num[endList].x = a;
num[endList].y = b;
next[endList] = hash[code];
hash[code] = endList++;
}
bool find(int a, int b){
if(a > b){
int t = a;
a = b;
b = t;
}
int code = (a * smod + b) % mod;
for (int i = hash[code]; i > -1;i = next[i])
if(num[i].x == a && num[i].y == b)
return true;
return false;
}
int main(){
int n, m, temp = 0;
while(n = input(), m = input(),n , m){
++temp ;
int x, y;
endList = 0;
memset(hash,-1,sizeof hash);
for(int i = 0; i < m; ++i){
x = input();
y = input();
//scanf("%d%d", &x, &y);
if(x > y){
insert(y, x);
}
else{
insert(x, y);
}
}
int front = 0;
int rear = 0;
que[front] = 1;
for(int i = 2; i <= n; ++i){
point[i]=i;
}
int sum = 0;
while(front <= rear){
for(int i = 2; i <= n; ){
if(!find(que[front], point[i])){
rear++;
que[rear] = point[i];
point[i] = point[n];
n--;
sum++;
}
else{
i++;
}
}
front++;
}
printf("Case %d: %d\n", temp, sum);
}
return 0;
}
第三种,关键是数组模拟,链表。不贴了
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator