POI2001 Ants and the ladybug ***
2011-10-07 00:40
288 查看
直接模拟, 刚开始把题意理解错了,以为每次只有一只蚂蚁走,其实正确的是蚂蚁一哄而上,然后按照题意,各只蚂蚁分别在该停的位置停下。
先转一个吧: http://www.byvoid.com/blog/poi-2001-mro/
做出这道题关键在于读懂题目,尤其是第3条和第4条规则。可以知道,所有蚂蚁是一拥而上的,而且蚂蚁很聪明,它们知道如果在某时一只蚂蚁到瓢虫的路 径与另一只蚂蚁的路径相互包含,就让距离近的蚂蚁继续行进,另一只蚂蚁停留不动。蚂蚁们还会互相礼让,如果要同时进入一个节点,就让编号小的蚂蚁进入,其 它蚂蚁停止不再动。
瓢虫会停留在多个位置,但是都是互相不关联的,我们可以把瓢虫停留的每个位置看作独立的测试点,每个测试点要用到上个测试点的结果,所以我们可以分割考虑每次瓢虫停留。
对于每次瓢虫停留,如果简单地模拟,会很容易超时。我们要把每只蚂蚁一次移动到位。首先从瓢虫的位置开始一遍BFS,找到所有可行进的蚂 蚁,记录每只蚂蚁到瓢虫位置的路径。然后按照路径长度从小到大为第一关键字,蚂蚁编号从小到大为第二关键字把蚂蚁进行排序,排名第一的蚂蚁一定是可以驱逐 瓢虫的蚂蚁,把它的路径上的顶点分别标记时间。然后依次处理每只蚂蚁,如果某只蚂蚁路径上有节点已经被标记时间,则这只蚂蚁的最大移动时间就是已经标记的 时间。在移动时也标记时间,用于影响后面的蚂蚁。这样,移动所有蚂蚁的时间复杂度是O(N+K)的。
算法的总的时间复杂度为O((N+K*logK)*L),可以很快解决问题。实际编写时有很多细节需要注意。
------------------------------------------------------------------------------------------------------------------------
下面是自己写的错误理解的代码,也贴上来吧:
先转一个吧: http://www.byvoid.com/blog/poi-2001-mro/
做出这道题关键在于读懂题目,尤其是第3条和第4条规则。可以知道,所有蚂蚁是一拥而上的,而且蚂蚁很聪明,它们知道如果在某时一只蚂蚁到瓢虫的路 径与另一只蚂蚁的路径相互包含,就让距离近的蚂蚁继续行进,另一只蚂蚁停留不动。蚂蚁们还会互相礼让,如果要同时进入一个节点,就让编号小的蚂蚁进入,其 它蚂蚁停止不再动。
瓢虫会停留在多个位置,但是都是互相不关联的,我们可以把瓢虫停留的每个位置看作独立的测试点,每个测试点要用到上个测试点的结果,所以我们可以分割考虑每次瓢虫停留。
对于每次瓢虫停留,如果简单地模拟,会很容易超时。我们要把每只蚂蚁一次移动到位。首先从瓢虫的位置开始一遍BFS,找到所有可行进的蚂 蚁,记录每只蚂蚁到瓢虫位置的路径。然后按照路径长度从小到大为第一关键字,蚂蚁编号从小到大为第二关键字把蚂蚁进行排序,排名第一的蚂蚁一定是可以驱逐 瓢虫的蚂蚁,把它的路径上的顶点分别标记时间。然后依次处理每只蚂蚁,如果某只蚂蚁路径上有节点已经被标记时间,则这只蚂蚁的最大移动时间就是已经标记的 时间。在移动时也标记时间,用于影响后面的蚂蚁。这样,移动所有蚂蚁的时间复杂度是O(N+K)的。
算法的总的时间复杂度为O((N+K*logK)*L),可以很快解决问题。实际编写时有很多细节需要注意。
/* * Problem: POI2001 mro * Author: Guo Jiabao * Time: 2009.2.2 21:43 * State: Solved */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> using namespace std; const int MAXN=5001,MAXK=1001,INF=0x7FFFFFFF; struct edge{int t;edge *next;}; struct adjl{edge *f,*l;}; struct vertex{int id,ant,label;}; struct ant{int vtx,id,dist,hits;}; struct path{path *from;int p;}; edge E[MAXN*2]; adjl A[MAXN]; vertex V[MAXN]; ant Ant[MAXK]; int PL[MAXK],Pt[MAXK][MAXN]; int N,K,L,Ec=-1,Target; int Order[MAXK]; inline void addedge(int a,int b) { if (A[a].f) A[a].l=A[a].l->next=&E[++Ec]; else A[a].f=A[a].l=&E[++Ec]; E[Ec].t=b; } void init() { int i,a,b; freopen("mro.in","r",stdin); freopen("mro.out","w",stdout); scanf("%d",&N); for (i=1;i<N;i++) { scanf("%d%d",&a,&b); addedge(a,b); addedge(b,a); } for (i=1;i<=N;i++) V[i].id=i; scanf("%d",&K); for (i=1;i<=K;i++) { scanf("%d",&a); V[a].ant=i; Ant[i].id=i; Ant[i].vtx=a; Order[i]=i; } scanf("%d",&L); } void BFS() { path Queue[MAXN],u,v; int Head=0,Tail=0; bool vis[MAXN]; int *P; memset(vis,0,sizeof(vis)); Queue[0].p=Target; Queue[0].from=0; vis[Target]=true; while (Head<=Tail) { v.from=&Queue[Head]; u=Queue[Head++]; for (edge *k=A[u.p].f;k;k=k->next) { v.p=k->t; if (!vis[v.p]) { vis[v.p]=true; if (V[v.p].ant!=0) { int a=V[v.p].ant; path *b=&v; PL[a]=0; P=Pt[a]; while (b->from) { P[++PL[a]]=b->p; b=b->from; } P[++PL[a]]=Target; Ant[a].dist=PL[a]-1; } else Queue[++Tail]=v; } } } } void Move() { int p,i,j,u,v,MaxStep,Step; i=Order[1]; Ant[i].hits++; MaxStep=PL[i]; for (p=1;p<=K && Ant[i=Order[p]].dist<INF;p++) { Step=MaxStep; for (j=1;j<=PL[i];j++) { u=Pt[i][j]; if (V[u].label) { Step=V[u].label+1; break; } } u=Pt[i][1]; V[u].ant=0; for (j=2;j<=Step;j++) { v=Pt[i][j]; if (V[u].label+1 > V[v].label) V[v].label=V[u].label+1; else break; u=v; } Ant[i].vtx=u; V[u].ant=i; } } inline int cmp(const void *a,const void *b) { int A=*(int *)a,B=*(int *)b; if ( Ant[A].dist < Ant[B].dist ) return -1; if ( Ant[A].dist > Ant[B].dist ) return 1; if ( Ant[A].id < Ant[B].id ) return -1; return 1; } void clear() { int i; for (i=1;i<=K;i++) Ant[i].dist=INF; for (i=1;i<=N;i++) V[i].label=0; } void solve() { int i,a; for (i=1;i<=L;i++) { scanf("%d",&Target); if (V[Target].ant!=0) { a=V[Target].ant; Ant[a].hits++; } else { clear(); BFS(); qsort(Order+1,K,sizeof(Order[0]),cmp); Move(); } } for (i=1;i<=K;i++) { printf("%d %dn",Ant[i].vtx,Ant[i].hits); } } int main() { init(); solve(); return 0; }
------------------------------------------------------------------------------------------------------------------------
下面是自己写的错误理解的代码,也贴上来吧:
/* * Ants and the ladybug .cpp * * Created on: 2011-10-6 * */ #include <cstdio> #include <cstring> using namespace std; const int maxN = 5000 + 5; const int maxK = 1000 + 5; const int maxL = 500 + 5; int n, k, l, antPos[maxK], chaseTime[maxK] = {}; int queue[maxN], head, tail; bool vis[maxN] = {}; struct SList{ int to; SList *next; SList(): next(NULL) {} }; struct STree{ int antNum; SList list; STree(): antNum(-1) {} }; STree tree[maxN]; void cal(int bugPos){ //bug所在位置就有蚂蚁 if(tree[bugPos].antNum != -1){ antPos[tree[bugPos].antNum] = bugPos; chaseTime[tree[bugPos].antNum]++; return; } SList *tmpList = &tree[bugPos].list; bool flag = 0; int minNum = maxK, cur; head = tail = 0; vis[bugPos] = 1; while(tmpList->next != NULL){ if(tree[tmpList->next->to].antNum != -1){ flag = 1; //记录相同距离的编号最小的蚂蚁。。 if(minNum > tree[tmpList->next->to].antNum) minNum = tree[tmpList->next->to].antNum; } queue[tail++] = tmpList->next->to; vis[tmpList->next->to] = 1; tmpList = tmpList->next; } //距离为1的节点有蚂蚁 if(flag){ tree[antPos[minNum]].antNum = -1; antPos[minNum] = bugPos; tree[bugPos].antNum = minNum; chaseTime[minNum]++; return; } //插桩,即记录BFS每一层结束的位置,以确定蚂蚁到bug的距离。。 queue[tail++] = -1; while(head != tail){ cur = queue[head++]; //遇到桩了,说明一层以结束,检查这一层是否有蚂蚁(即离bug最近的蚂蚁),如果没有,继续下一层搜索 if(cur == -1){ queue[tail++] = -1; if(flag){ //有蚂蚁 tree[antPos[minNum]].antNum = -1; antPos[minNum] = bugPos; tree[bugPos].antNum = minNum; chaseTime[minNum]++; return; } continue; } tmpList = &tree[cur].list; while(tmpList->next != NULL){ //已经访问过 if(vis[tmpList->next->to]){ tmpList = tmpList->next; continue; } //有蚂蚁 if(tree[tmpList->next->to].antNum != -1){ flag = 1; if(minNum > tree[tmpList->next->to].antNum) minNum = tree[tmpList->next->to].antNum; } queue[tail++] = tmpList->next->to; vis[tmpList->next->to] = 1; tmpList = tmpList->next; } } } int main(){ //输入n scanf("%d", &n); int a, b; SList *tmpNode; for(int i=0; i<n-1; i++){ scanf("%d %d", &a, &b); tmpNode = &tree[a].list; while(tmpNode->next != NULL) tmpNode = tmpNode->next; tmpNode->next = new SList; tmpNode = tmpNode->next; tmpNode->to = b; tmpNode->next = NULL; tmpNode = &tree[b].list; while(tmpNode->next != NULL) tmpNode = tmpNode->next; tmpNode->next = new SList; tmpNode = tmpNode->next; tmpNode->to = a; tmpNode->next = NULL; } //输入K scanf("%d", &k); int tmpPos; for(int i=0; i<k; i++){ scanf("%d", &tmpPos); antPos[i] = tmpPos; tree[tmpPos].antNum = i; } //输入L scanf("%d", &l); for(int i=0; i<l; i++){ memset(vis, 0, sizeof(vis)); scanf("%d", &tmpPos); cal(tmpPos); } //输出 for(int i=0; i<k; i++){ printf("%d %d\n", antPos[i], chaseTime[i]); } return 0; }
相关文章推荐
- InvalidArgumentError : Shape in shape_and_slice spec [,] does not match the shape stored in checkpoi
- Report on Environmental Monitoring in the College Archives and Sophia Smith Collection Conducted by the Massachusetts Board of Library Commissioners, August 2001-Janaury 2002
- Angel Borja博士教你如何撰写科学论文三:Writing the first draft of your science paper — some dos and don’ts
- hdu 1029 Ignatius and the Princess IV
- Drawing lines in Mozilla based browsers and the Internet Explorer
- Types and Declarations(Chapter 4 of The C++ Programming Language)
- HDU3988-Harry Potter and the Hide Story(数论-质因数分解)
- 【python】升级pip后报错解决pkg_resources.DistributionNotFound: The 'pip==7.1.0' distribution was not found and is required by the application
- Oracle: What is the ORACLE_SID and DB_NAME name ?
- what is the difference between definition and declaration in c
- IDEA There is no configured/running web-servers found! Please, run any web-configuration and hit the Refresh button!
- SCSF - Part 8 Creating and Using Services in the CAB
- SQL - How to get the current day, month and year
- Android Theme and Menu 主题菜单相关
- [Android]ADT Run时候报错:The connection to adb is down, and a severe error has occured
- Leetcode 2. Add Two Numbers The Solution of Python and Javascript
- POJ 3312 Mahershalalhashbaz, Nebuchadnezzar, and Billy Bob Benjamin Go to the Regionals (水题,贪心)
- Symbolic Data Analysis and the SODAS Software
- Security Domains and the Domain Account Manager (Windows)
- Scraping the Dynamic Web with PhantomJS: Using jQuery and Node: James Morrin: 9781449321864: Amazon.com: Books