| ||||||||||
| 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