POJ 1659 Frogs' Neighborhood

老师说是阿基米定律的题,根据每个点的度数判断这些点能不能构成图。

实则用起来我认为是一种贪心的思想,举个栗子:(首先不可能有点的度数为负

(1)各个点的度数 4 3 1 5 4 2 1 (每次都从大到小排序)

5 4 4 3 2 1 1,先解决度数最多的点他有5个邻居(是邻居,那度数-1),当然是优先考虑他后面的5个,因为是相较而言邻居(度数)比较多的,如果先考虑度数少的,那它的度数很快为负,显然不合理

3 3 2 1 1 0 -> 2 1 1 0 0 -> 0 0 0 0   最后变成了一个全是0的序列,说明各个点的度数恰好匹配,能构成一个所给序列度数的图。

(2)各个点的度数 4 3 1 4 2 0

4 4 3 2 1 0 -> 3 2 1 0 0 ->1 0 -1 0  出现一个点a的度数为负数了,说明这个图肯定构成不了了,因为是从大到小排序的,所以最大的点选择和a或a后面的点当邻居,都会使其度数为负

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int T,N;
struct S{
	int id;
	int num;
}f[1000];
int tt[20][20];
bool cmp(S a,S b){
	return a.num>b.num; 
}
bool solve(){
	for(int i=1;i<=N;++i){
		sort(f+i,f+1+N,cmp);//每次去掉一个最大的排序
		int num=f[i].num;//最大的那个数
		for(int j=i+1;j<=i+num;++j){//在这个数后面的num位都-1,减去一个度
			tt[f[i].id][f[j].id]=1;//标记一下他们是联通的
			tt[f[j].id][f[i].id]=1;
			f[j].num--;//度数-1
			if(f[j].num<0){//如果度数<0了,则说明这个图不能联通了,因为度数不可能为负数
				return 0;
			}
		}
		
	}
	return 1;
}
int main(){
	scanf("%d",&T);
	while(T--){
		memset(tt,0,sizeof(tt));
		scanf("%d",&N);
		for(int i=1;i<=N;++i){
			cin>>f[i].num;
			f[i].id=i;
		}
		if(solve()){
			cout<<"YES"<<endl;
			for(int i=1;i<=N;++i){
				for(int j=1;j<=N;++j){
					cout<<tt[i][j]<<' ';
				}
				cout<<endl;
			}
		}
		else cout<<"NO"<<endl;
		cout<<endl;
	}
	
	return 0;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值