zoj 3761 Easy billiards(dfs搜索树)
2014-03-02 17:38
351 查看
题意:平面有n个台球,每次可以选择一个台球,让它向着水平或垂直的方向,遇到其它台球它就会停在这个位置,而被击中的球继续前进,不能让一个球向着没有球的方向运动,最外面的球会被打出去。问最后最少能剩多少球。
思路:把所有的点与其相邻的点连边,这个可以通过两次排序解决,然后是一个一个去删点。首先,同一个连通块的肯定会被消成一个。对于这样的联通块,任意选一个点开始dfs,会生成一棵dfs搜索树,从叶子节点往上删,这样一定能全部删掉。
代码:
思路:把所有的点与其相邻的点连边,这个可以通过两次排序解决,然后是一个一个去删点。首先,同一个连通块的肯定会被消成一个。对于这样的联通块,任意选一个点开始dfs,会生成一棵dfs搜索树,从叶子节点往上删,这样一定能全部删掉。
代码:
#include <iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=2000+10; const int maxm=8000+10; const char * str[4]={"LEFT","RIGHT","UP","DOWN"}; struct Node { int x,y,id; Node(){} Node(int x,int y,int id):x(x),y(y),id(id){} }node[maxn]; struct Edge { int v,next; Edge(){} Edge(int v,int next):v(v),next(next){} }edges[maxm<<1]; int head[maxn],degree[maxn],nEdge,n; int hash[maxn][2],tot,cnt; int flag[maxn],S[maxn]; bool inq[maxn]; vector<pair<int,int> >ans; void AddEdges(int u,int v) { edges[++nEdge]=Edge(v,head[u]); head[u]=nEdge; edges[++nEdge]=Edge(u,head[v]); head[v]=nEdge; } bool cmp1(Node a,Node b) { return (a.x==b.x&&a.y<b.y)||(a.x<b.x); } bool cmp2(Node a,Node b) { return (a.y==b.y&&a.x<b.x)||(a.y<b.y); } void Init() { memset(head,0xff,sizeof(head)); memset(degree,0,sizeof(degree)); memset(flag,0,sizeof(flag)); memset(inq,0,sizeof(inq)); nEdge=-1;tot=cnt=0; ans.clear(); } void getans(int u,int v) { if(hash[u][0]==hash[v][0]) { if(hash[u][1]<hash[v][1]) ans.push_back(make_pair(u,2)); else ans.push_back(make_pair(u,3)); } else { if(hash[u][0]>hash[v][0]) ans.push_back(make_pair(u,0)); else ans.push_back(make_pair(u,1)); } } void dfs(int u) { flag[u]=tot; S[cnt++]=u; for(int k=head[u];k!=-1;k=edges[k].next) { int v=edges[k].v; if(flag[v]) continue; dfs(v); getans(v,u); } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d",&n)) { int x,y; Init(); for(int i=1;i<=n;++i) { scanf("%d%d",&x,&y); node[i]=Node(x,y,i); hash[i][0]=x;hash[i][1]=y; } sort(node+1,node+n+1,cmp1); for(int i=2;i<=n;++i) { if(node[i].x==node[i-1].x) { AddEdges(node[i].id,node[i-1].id); degree[node[i].id]++; degree[node[i-1].id]++; } } sort(node+1,node+n+1,cmp2); for(int i=2;i<=n;++i) { if(node[i].y==node[i-1].y) { AddEdges(node[i].id,node[i-1].id); degree[node[i].id]++; degree[node[i-1].id]++; } } int block=0; for(int i=1;i<=n;++i) { if(!flag[i]) { cnt=0;++tot; dfs(i); block++; } } printf("%d\n",block); int size=ans.size(); for(int i=0;i<size;++i) { int u=ans[i].first; printf("(%d, %d) %s\n",hash[u][0],hash[u][1],str[ans[i].second]); } } return 0; }
相关文章推荐
- ZOJ 3761 Easy billiards (DFS性质)
- zoj 3761 Easy billiards(建图+贪心+dfs)
- ZOJ 3761——Easy billiards(DFS,并查集)
- ZOJ 3761 Easy billiards[dfs]
- [贪心+dfs] ZOJ 3761 Easy billiards
- zoj 3761 Easy billiards 乱搞
- zoj 3761 Easy billiards 并查集+dfs
- ACM-ZOJ 2412 DFS 深度优先搜索
- hdu 1045 || zoj 1002 Fire Net(搜索:DFS+水题)
- ZOJ 2008 Gnome Tetravex 搜索(DFS)
- [ZOJ 1011] NTA (dfs搜索)
- zoj1711 dfs搜索+去重
- ZOJ 3761 Easy billiards 月赛E DFS
- Zoj 3761 Easy billiards dfs
- zoj 3761 Easy billiards
- ZOJ 3761 —— Easy billiards(并查集+深搜)
- zoj 3761 Easy billiards
- Valid Pattern Lock-ZOJ 暴力DFS搜索
- Easy billiards (zoj 3761 并查集+DFS)
- [ZOJ 1003] Crashing Balloon (dfs搜索)