题目链接:传送门
题意:
感觉这次读题特别重要啊“这些点满足任意三点不共线。他把一些点用线段连起来了,但是任意两条线段不会在端点以外相交”这是题目给的原话,但是比赛的时候一直没有用。。。然后就SB了,因为平面图两两相连而且不相交的点集最大就为4,那么就可以分别来考虑了。
首先考虑最大为4的情况,分别枚举两条边,如果这两条边没有公共点,而且顶点两两相连那么就是一个符合的。
如果最大为3的话,那么就可以枚举一条边,然后再枚举点就可以了。
如果最大为2,就输出边数。最大为1的话就输出点的个数。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <set>
using namespace std;
const int maxn = 1010;
int head[maxn];
struct nod{
int u,v;
}edge[maxn*maxn];
bool mp[maxn][maxn];
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
int x,y;
for(int i=0;i<n;i++) scanf("%d%d",&x,&y);
memset(mp,0,sizeof(mp));
for(int i=0;i<m;i++){
scanf("%d%d",&x,&y);
edge[i].u=x;
edge[i].v=y;
mp[x][y]=1,mp[y][x]=1;
}
if(m==0){
printf("1 %d\n",n);
continue;
}
int sum=0;
for(int i=0;i<m;i++){
int u=edge[i].u,v=edge[i].v;
for(int j=i+1;j<m;j++){
int u1=edge[j].u,v1=edge[j].v;
if(u1==u||v1==v||u1==v||v1==u) continue;
if(mp[u1][v]&&mp[v1][u]&&mp[u][u1]&&mp[v][v1]) sum++;
}
}
if(sum){
printf("4 %d\n",sum/3);
continue;
}
for(int i=0;i<m;i++){
int u=edge[i].u,v=edge[i].v;
for(int j= 1;j<=n;j++){
if(j==v||j==u) continue;
if(mp[u][j]&&mp[v][j]) sum++;
}
}
if(sum){
printf("3 %d\n",sum/3);
continue;
}
else
printf("2 %d\n",m);
}
return 0;
}