Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
该题SPFA算法思想运用,邻接表加队列题意讲的是奶牛排名,本可以用Floyd来解,但是SPFA会更快,说是SPFA,其实只是用了它的队列加邻接表的思想,要给n个奶牛排名,就是求排在该奶牛前面和后面的奶牛之和,如果和是n-1,那么这个奶牛的排名就是确定的,先正向将奶牛的关系存入邻接表中,不用存权值,开一个cnt数组用于统计能被当前奶牛打败的牛,然后遍历每一个奶牛,先标记当前奶牛,存入队列,遍历队首奶牛的关系,即找到邻接表中能被当前奶牛打败的奶牛,找到一个就让以队首奶牛为下标的cnt数组加加,然后标记当前找到的奶牛,并将当前这头放入队列中,循环到队空,那么cnt数组中就存下了排在cnt数组下标后面的牛的个数,然后清空邻接表,反向将奶牛关系存入邻接表中,不清cnt数组,再用上面的方法做一遍,最后cnt数组中值为n-1的个数就是能确定排名的牛的个数。 附上代码: #include<cstdio> #include<stdlib.h> #include<cstring> #include<queue> #include<algorithm> #define N 105 #define M 4505 using namespace std; int V,E; struct node { int u,v,next; }G[M]; struct node1 { int x,y; }Cow[M]; int head[N],e; int vis[N]; int cnt[N]; void add(int u,int v) { G[e].u=u; G[e].v=v; G[e].next=head[u]; head[u]=e++; } void SPFA(int s) { queue<int>que; for(int i=1; i<=V; i++) vis[i]=0; vis[s]=1; que.push(s); while(!que.empty()) { int temp=que.front(); que.pop(); for(int i=head[temp]; i!=-1; i=G[i].next) { int v=G[i].v; if(!vis[v]) { cnt[s]++; vis[v]=1; que.push(v); } } } } int main() { while(~scanf("%d%d",&V,&E)) { memset(head,-1,sizeof(head)); memset(cnt,0,sizeof(cnt)); e=0; for(int i=1; i<=E; i++) { scanf("%d%d",&Cow[i].x,&Cow[i].y); add(Cow[i].x,Cow[i].y); } for(int i=1;i<=V;i++) SPFA(i); memset(head,-1,sizeof(head)); e=0; for(int i=1; i<=E; i++) add(Cow[i].y,Cow[i].x); for(int i=1;i<=V;i++) SPFA(i); int ans=0; for(int i=1;i<=V;i++) if(cnt[i]==V-1) ans++; printf("%d\n",ans); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator