题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=211
思路:我的思路是对每一个点,向上广搜,向下广搜,看总共能不能搜到n-1个结点,能,表明该节点的等级确定。
题目标程给的方法是floyd+统计,似乎简单的多,我弄复杂了,还是贴个代码吧!
代码如下:
#include "stdio.h" #include "string.h" #include "queue" using namespace std; #define N 105 #define M 4505 #define INF 0x3fffffff struct node { int x,y; int next; }edge[2*M]; int idx,head[N]; void Init(){ idx=0; memset(head,-1,sizeof(head)); } void Add(int x,int y) { edge[idx].x=x; edge[idx].y=y; edge[idx].next = head[x]; head[x] = idx++; } bool mark[N]; void BFS(int k) { int i; int x,y; queue<int> q; q.push(k); mark[k] = true; while(!q.empty()) { x = q.front(); q.pop(); for(i=head[x]; i!=-1; i=edge[i].next) { y = edge[i].y; if(!mark[y]) q.push(y); mark[y] = true; } } mark[k] = false; } struct point { int x,y; }p[2*M]; int num[N],num1[N],num2[N]; int main() { int n,m; int i,j; while(scanf("%d %d",&n,&m),n||m) { Init(); //建邻接表初始化 for(i=0; i<m; ++i) { scanf("%d %d",&p[i].x,&p[i].y); Add(p[i].x,p[i].y); } for(i=1; i<=n; ++i) //对每个点,往下搜,统计能搜多少个点 { num1[i]=0; memset(mark,false,sizeof(mark)); BFS(i); for(j=1; j<=n; ++j) //统计 { if(mark[j]) num1[i]++; } } Init();//建邻接表初始化 for(i=0; i<m; ++i) Add(p[i].y,p[i].x); //再次建邻接表,反向的 for(i=1; i<=n; ++i) //对每个点,往上搜,统计能搜多少个点 { num2[i]=0; memset(mark,false,sizeof(mark)); BFS(i); for(j=1; j<=n; ++j) { if(mark[j]) num2[i]++; } } int ans = 0; for(i=1; i<=n; ++i) { num[i] = num1[i]+num2[i]; if(num[i]==n-1) ans++; } printf("%d ",ans); } return 0; }