题意:已知有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我就没搞定。