t組數據,然後n個關係,每個關係兩個值x,y,表示x和y不互相認識,求分爲兩組的人每組內的人必須互相認識的人數,
其中一組儘可能大(最大值和最小值),如果不存在,輸出Poor wyh
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int E=0;
int n;
const int MAXV = 100005;
int head[MAXV],poi[2*MAXV],col[MAXV];
int nxt[MAXV*2];
int num[3];
void add(int u,int v)
{
nxt[E]=head[u];
poi[E]=v;
head[u]=E++;
}
bool color(int u){ //染色法求各個聯通快內二分圖的最小覆蓋點(最大匹配)
if(!col[u]) col[u]=1;
num[col[u]]++;
for(int i=head[u];i!=-1;i=nxt[i]){
int v=poi[i];
if(!col[v]){
col[v]=3-col[u];
if(!color(v)) return 0;
}
else if(col[v]==col[u]) return 0;
}
return 1;
}
int main()
{
int m,t;
scanf("%d",&t);
while(t--){
E=0;
memset(head,-1,sizeof(head));
memset(col,0,sizeof(col));
memset(num,0,sizeof(num));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
if(n<=1) {
puts("Poor wyh");
continue;
}
if(m==0){
printf("%d %d\n",n-1,1);
continue;
}
int flag=0;
int m1=0;
int m2=0;
for(int i=1;i<=n;i++){
if(!col[i]){
int c1=num[1];
int c2=num[2];
if(!color(i)){
printf("Poor wyh\n");
flag=1;
break;
}
m1+=max(num[1]-c1,num[2]-c2); //把各個聯通塊的的最大值相加,最小值相加
m2+=min(num[1]-c1,num[2]-c2);
}
}
if(flag) continue;
printf("%d %d\n",m1,m2);
}
}