Description
中南大学ACM的暑期集训马上就要开始了,这次集训会将全体N名集训队员(编号分别为1, 2, …, N)按集训选拔赛的排名分成两组,前K名队员分入A组,其余队员分入B组。
但现在助理教练CSGrandeur一不小心把集训选拔赛的排名弄丢了,而之前又没将A组和B组的人员确定出来,于是CSGrandeur打算问一下集训人员他们的名次各是怎样的,以此来确定一下A组的队员。
然而集训队员们都视名次如粪土,只是隐约记得某些人排在了自己的后面,最终反馈到CSGrandeur这里的一共有M条信息,每条信息都可以用一个二元组(x, y) (x!=y)表示,含义为第x名队员记得第y名队员的排名比自己的要靠后。
现在CSGrandeur想知道,根据这M条信息,是否可以确定出A组的队员呢?(默认所有集训队员反映的信息都是符合事实的。)
Input
输入包含多组测试数据。
对于每组测试数据,第一行包含三个正整数N (2<=N<=1000)、K (1<=K<=N)、M (1<=M<=10000),含义同上。接下来M行每行有两个正整数x、y (1<=x, y<=N且x!=y),分别描述了M条信息,对于每对x、y,均表示第x名队员记得第y名队员的排名比自己的要靠后。
Output
Sample Input
3 1 21 21 33 2 21 21 3
Sample Output
YESNO
数学模型:给定n个未知数,m组关系,没组关系指出n个未知数中的2个的大小关系,例如A>B,求能否据此确定前k个数的集合?
一开始想到并查集,写了好几次都WA了,最后发现此题中的关系并不是等价关系。后来想到一个类似的题,那题也是给定n个未知数和一些大小关系,要求的是能否确定所有数的大小关系。那题是用拓扑排序做的。用拓扑排序的方法很容易找出一组符合条件的解,关键在于如何判断解的唯一性,如果解是唯一的,那么剩下的n-k个数一定在所选的k个数的后面,也就是从这所选的k个数(图中表示为结点)中任意一个出发,可以遍历到剩下的n-k个数。问题也就解决了。
1 #include2 #include 3 #include 4 #define N 1001 5 using namespace std; 6 vector g[N]; 7 int n,k,m,cnt,d[N],a[N],vis[N],flag[N]; 8 void dfs(int u) 9 {10 int i,v;11 if(flag[u]==0 && vis[u]==0) cnt++;12 vis[u]=1;13 for(i=0;i