hdu1941 Justice League

点击打开链接

题意:已知有H个英雄,和他们之间的关系。现在的任务是让你从里边选出一个正义联盟(条件是任意两个成员都认识),则剩下的就自动成为非正义联盟(条件是任意两个都不认识)。如果可以构成的话输出Y,否则输出N。

解题思路:在输入的时候记录每个点的度数,然后对他们的度数排序。用临接表(在这里用的vetor)记录每个点相邻的点,从度数最小的点开始删并且让他相邻点度数减一,和进行标记使他们都不能再被删除。删完之后判断剩下的点是否可以构成一个无向完全图即可。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
int h,r;
int a[50009],pos[50009],vis[50009];
struct node
{
    vector<int> next;
}b[50009];
bool cmp(int x,int y)
{
    return a[x]<a[y];
}
void init()
{
    for(int i=1;i<=h;i++)
    {
        a[i]=0;
        b[i].next.clear();//每次都需将vcetor清空
        vis[i]=0;
    }
}
int slove()
{
    int s=0,flag=0;
    for(int i=1;i<=h;i++)
    {
        if(a[i]>-1)
        {
            s++;
        }
    }
    for(int i=1;i<=h;i++)
    {
        if(a[i]>-1)
        {
            if(a[i]!=s-1)
            {
                flag=1;
                break;
            }

        }
    }
    return flag;
}
int main()
{
   while(cin>>h>>r)
   {
       if(h==0&&r==0)
        {
            break;
        }
        init();
        for(int i=1;i<=r;i++)
        {
            int p,q;
            cin>>p>>q;
            a[p]++;//记录赌输
            a[q]++;
            b[p].next.push_back(q);//记录相邻的点
            b[q].next.push_back(p);
        }
        for(int i=1;i<=h;i++)
        {
            pos[i]=i;
        }
        sort(pos+1,pos+h+1,cmp);//安度数排序
        for(int i=1;i<=h;i++)
        {
            if(!vis[pos[i]])
            {
                a[pos[i]]=-1;
                for(int j=0;j<b[pos[i]].next.size();j++)
                {
                    a[b[pos[i]].next.at(j)]--;
                    vis[b[pos[i]].next.at(j)]=1;
                }
            }
        }
        sort(a+1,a+h+1);
       if(!slove())
       {
           cout<<"Y"<<endl;
       }
       else
       {
           cout<<"N"<<endl;
       }

   }
   return 0;
}

用java写我放弃了,因为sort的那个cmp我就没搞定。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值