HDU 5277 YJC counts stars
Chieh
posted @ 2015年7月05日 11:43
in BestCoder
, 302 阅读
飞机票:http://acm.hdu.edu.cn/showproblem.php?pid=5277
题意:就是给你n个点n个坐标xi,yi(1<=i<=n),然后给你m条边,表示u和v相连,保证没重边,也保证没有边相交。然后 让你求最大的点子集,使里面的点可以两两相连(不是图相连,线段相连),且求处个数。
分析:其实分析分析,就发现最大就只有4个点的点急,因为5个点就会有边相交,与题目不符,所以只要枚举到4个点就行了,具体怎么枚举才比较好?可以先枚举两两的,就是加入i和j有边相连,就把i和j算一对保存起来,这样我们就知道两两相连的子集个数有多少个了,怎么枚举三个的,很简单,只要把两个相连的与一个个点比较,只要这两个点能同事与第三个点连接,那么就是ok的,这里注意:假设i和j和k是属于三个相连的,我们求出来两两的就是(i,j)(i,k)(j,k)然后枚举三个点的时候会有三种方法,但是实际上就只有1种,所以答案要/3,这样我们就知道三个点的自己个数了,现在是四个点了,四个点也很方便,只要把两个点的两两进行判断就行了,只要互不相同然后互相连接就可以了,但是要注意:假设我们i,j,p,q,是四个相连的点集,那么我们两两求出来的就是(i,j)(i,p)(i,q)(j,p)(j,q)(p,q),这样的话,他们两两按数序的话会求出来三组,因为我们重复计算了,所以答案要/3到此为止,所有的都已经判断了, 按照4,3,2,1只要有一个是满足的,直接ok,结束。然后啪啪啪就可以AC了
/* Author:Chieh Because Of Coding */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #include <stack> #define LL long long #define INF 1e9 #define EPS 1e-9 using namespace std; const int maxn=1234; int x[maxn],y[maxn]; int ai[maxn][maxn]; int n,m; void init() { for(int i=1; i<=n; i++)scanf("%d%d",&x[i],&y[i]); int u,v; memset(ai,0,sizeof(ai)); for(int i=1; i<=m; i++) { scanf("%d%d",&u,&v); ai[u][v]=ai[v][u]=1; } } int bi[maxn*maxn][2]; void play() { if(m==0) { printf("1 %d\n",n); return; } if(m==1) { printf("2 1\n"); return ; } int st=1; int sum2=0; //判断连通性 for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { if(ai[i][j]) { bi[st][0]=i; bi[st][1]=j; st++; sum2++; } } } int sum3=0; //判断三个点的 for(int i=1; i<st; i++) { for(int j=1; j<=n; j++) { int u=bi[i][0]; int v=bi[i][1]; if(ai[u][j]&&ai[v][j]) { sum3++; } } } int sum4=0; //判断四个点的 for(int i=1; i<st; i++) { for(int j=i+1; j<st; j++) { int u1=bi[i][0]; int u2=bi[i][1]; int v1=bi[j][0]; int v2=bi[j][1]; if(u1!=v1&&u1!=v2&&u2!=v1&&u2!=v2&&ai[u1][v1]&&ai[u1][v2]&&ai[u2][v1]&&ai[u2][v2])sum4++; } } if(sum4!=0) { printf("4 %d\n",sum4/3); } else if(sum3!=0) { printf("3 %d\n",sum3/3); } else if(sum2!=0) { printf("2 %d\n",sum2); } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { init(); play(); } // cout << "Hello world!" << endl; return 0; }