hdu 1102 Constructing Roads

跟之前的继续畅通工程几乎一模一样,只是输入换一下。map[i][j]!=0时,才将其做为一条边,否则不加入。

#include<iostream>
#include<algorithm>
using namespace std;

#define NUM 105
struct points
{
	int start;
	int end;
	int w;
}pos[10005];
int set[NUM];
int map[NUM][NUM];
void init()
{
	for(int i=0;i<NUM;++i)
		set[i]=i;
}

int find(int x)
{
	int r=x;
	while(r!=set[r])
		r=set[r];
	return r;
}

int find2(int x)//带路径压缩的查找(非递归版)   
{  
    int k, j, r;  
    r = x;  
    while(r != set[r])     //查找根节点   
        r = set[r];      //找到根节点,用r记录下   
    k = x;    
    while(k != r)             //非递归路径压缩操作   
    {          
		j = set[k];         //用j暂存set[k]的父节点   
		set[k] = r;        //set[x]指向根节点    
		k = j;                    //k移到父节点      
    }    
    return r;         //返回根节点的值   
}  

void merge(int x,int y)
{
	int a=find2(x);
	int b=find2(y);
	if(a!=b)
		set[a]=b;
	return;
}

int cmp(struct points a,struct points b)
{
	return a.w < b.w;
}

int main()
{
	int n,i,j,m,index,x,y,sum;
	freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);
	//while(cin>>n&&n!=0){
	while(scanf("%d",&n)!=EOF&&n!=0){
		index=0;
		sum=0;
		init();
		for(i=1;i<=n;++i){
			for(j=1;j<=n;++j){
				scanf("%d",&map[i][j]);
			}			
		}
		scanf("%d",&m);
		while(m--){
			scanf("%d%d",&x,&y);
			map[x][y]=0;
			merge(x,y);
		}
		for(i=1;i<=n;++i){
			for(j=1;j<=n;++j){
				if(map[i][j]!=0){
					pos[index].start=i;
					pos[index].end=j;
					pos[index].w=map[i][j];
					++index;
				}				
			}
		}

		sort(pos,pos+index,cmp);
		for(i=0;i<index;++i){
			if(find2(pos[i].start)!=find2(pos[i].end)){
				merge(pos[i].start,pos[i].end);
				sum+=pos[i].w;
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}


 

 

你可能感兴趣的:(hdu 1102 Constructing Roads)