Poj 1659 Frogs' Neighborhood

题意:中文题,至少不用苦心的去读题了。给出了n个湖泊的n个青蛙,依次给出n个青蛙的邻居关系,判断这种关系能否成立 。若能够成立,写出代表两个湖泊关系的邻接矩阵。

矩阵写法多种  所以special judge.......

Sample Input

3
7
4 3 1 5 4 2 1 
6
4 3 1 4 2 0 
6
2 3 1 1 2 1 

Sample Output

YES
0 1 0 1 1 0 1 
1 0 0 1 1 0 0 
0 0 0 1 0 0 0 
1 1 1 0 1 1 0 
1 1 0 1 0 1 0 
0 0 0 1 1 0 0 
1 0 0 0 0 0 0 

NO

YES
0 1 0 0 1 0 
1 0 0 1 1 0 
0 0 0 0 0 1 
0 1 0 0 0 0 
1 1 0 0 0 0 
0 0 1 0 0 0


思路:学到一种新的方法:havel算法。

/*Havel算法的思想简单的说如下:
(1)对序列从大到小进行排序。
(2)设最大的度数为 t ,把最大的度数置0,然后把最大度数后(不包括自己)的 t 个度数分别减1(意思就是把度数最大的点与后几个点进行连接)
(3)如果序列中出现了负数,证明无法构成。如果序列全部变为0,证明能构成,跳出循环。前两点不出现,就跳回第一步!

*/

有了这个,判断能否构成图就轻松多了,邻接矩阵则在每次判断中进行构建。


代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <climits>//形如INT_MAX一类的
using namespace std;
#define MAX 1050
#define INF 0x7FFFFFFF
# define eps 1e-5
struct node
{
    int index;
    int neigh;
} lake[11];
bool cmp(node a,node b)
{
    return a.neigh>b.neigh;
}
int map[11][11];
int main()
{
    int t,i,n,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=1; i<=n; i++)
        {
            scanf("%d",&lake[i].neigh);//每个青蛙周围的青蛙
            lake[i].index=i;//第n个青蛙
        }
        memset(map,0,sizeof(map));
        for(i=1;;)
        {
            sort(lake+1,lake+n+1,cmp);//havel第一步
            int index=0;
            for(j=i+1; j<=lake[i].neigh+1; j++)
            {
                lake[j].neigh--;//havel第二步
                if(lake[j].neigh<0)//havel第三步
                {
                    i=n;//为下个if(i!=n)判断
                    index=n;//此处赋值只是为了退出循环
                    printf("NO\n");
                    break;
                }
                map[lake[i].index][lake[j].index]=1;//这两行邻接矩阵构建,说明相连
                map[lake[j].index][lake[i].index]=1;
            }
            lake[i].neigh=0;//havel第二步
            if(index==n)
                break;
            for(int k=1; k<=n; k++)//所有为零 构成图
            {
                if(lake[k].neigh==0)
                {
                    index++;
                }
            }
            if(index==n)
                break;
        }
        if(i!=n)//对应上面
        {
            printf("YES\n");
            for(i=1; i<=n; i++)//输出邻接矩阵
            {
                for(j=1; j<=n-1; j++)
                {
                    printf("%d ",map[i][j]);
                }
                printf("%d\n",map[i][n]);
            }
        }
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值