生活真是奇妙的东西,这样的题目居然能被联想到这样的算法,只能说智商不够啊。
这道题目的意思不解释了,月赛的时候我队友已经想出来了做法,但是我们最后还是没A。
题解:
1。首先将所有能连接的球连接起来,然后看这个图有几个连通分量,那最后就会剩下几个球,这个用并查集实现下就好了。
由于xi,yi坐标比较分散所以要用邻接表进行存储。
2. 接下来就是输出方案,本来我们是想考虑点的度的,后来发现实现起来有点困难,实际上只需要按照并查集的唯一的头,进行深度优先搜索,这样就形成了一颗深搜树,
然后再用叶子节点打他的根节点就可以了。这样一次能打掉所有叶子节点(简直神奇)。
3.一开始进行2次排序,进行点的连接。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; int e,head[10005],root[10005],vis[10005]; struct node { int x,y; int nod,l; }s[10005],q[10005]; struct lj { int v; int next; }nn[10005]; int cmp1(struct node a,struct node b) { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } int cmp2(struct node a,struct node b) { if(a.y==b.y) return a.x<a.x; return a.y<b.y; } void link(int u,int v) { nn[e].v=v; nn[e].next=head[u]; head[u]=e++; } int find(int x) { if(x==root[x]) return x; else return root[x]=find(root[x]); } void dfs(int x) { int k; for(k=head[x];k!=-1;k=nn[k].next){ int v=nn[k].v; if(!vis[v]){ vis[v]=1; if(q[v].x==q[x].x){ if(q[v].y<q[x].y) q[v].l=4; else q[v].l=3; } if(q[v].y==q[x].y){ if(q[v].x<q[x].x) q[v].l=2; else q[v].l=1; } dfs(v); } } if(q[x].l==4) printf("(%d, %d) UP\n",q[x].x,q[x].y); else if(q[x].l==3) printf("(%d, %d) DOWN\n",q[x].x,q[x].y); else if(q[x].l==2) printf("(%d, %d) RIGHT\n",q[x].x,q[x].y); else if(q[x].l==1) printf("(%d, %d) LEFT\n",q[x].x,q[x].y); } int main() { int n,i; while(scanf("%d",&n)!=EOF){ e=1; memset(head,-1,sizeof(head)); for(i=0;i<n;i++){ scanf("%d %d",&s[i].x,&s[i].y); q[i].x=s[i].x;q[i].y=s[i].y; q[i].nod=s[i].nod=i; q[i].l=s[i].l=-1; } memset(vis,0,sizeof(vis)); for(i=0;i<n;i++) root[i]=i; sort(s,s+n,cmp1); for(i=1;i<n;i++){ if(s[i].x==s[i-1].x){ link(s[i].nod,s[i-1].nod); link(s[i-1].nod,s[i].nod); int ra=find(s[i].nod); int rb=find(s[i-1].nod); if(ra!=rb) root[rb]=ra; } } sort(s,s+n,cmp2); for(i=1;i<n;i++){ if(s[i].y==s[i-1].y){ link(s[i].nod,s[i-1].nod); link(s[i-1].nod,s[i].nod); int ra=find(s[i].nod); int rb=find(s[i-1].nod); if(ra!=rb) root[rb]=ra; } } int ans=0,father[3000]; for(i=0;i<n;i++){ if(root[i]==i){ father[ans++]=i; } } printf("%d\n",ans); for(i=0;i<ans;i++){ vis[father[i]]=1; dfs(father[i]); } } }
zoj 3761 Easy billiards 并查集+dfs,布布扣,bubuko.com
zoj 3761 Easy billiards 并查集+dfs
原文:http://blog.csdn.net/cnh294141800/article/details/20614845