Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

过了,提供3种方法:1,广搜+二分(1000到3500);2,广搜+hash(200到2000);3,暴力广搜(数组模拟链表,300左右)

Posted by yuan5531750 at 2011-08-28 16:38:49 on Problem 3697
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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator