标签:
题目链接:传送门
题目大意:一个家族有n个人,m种关系,之后行有 x y ,表示 x 是 y 的祖先,祖先具有传递性,然后有n个数,表示第 i 个人想把礼物送给 a[i],
你需要构造一张表这张表上的人代表收礼物的人,并且其他人送礼物是按表上的顺序找,找到的第一个祖先就是他要送礼的人,同时需要满足这个人
是他想送礼的人,如果存在这张表输出人数及编号,否则输出-1(题意中自己也算是自己的一个祖先)
题目思路:我们要从题意中得出结论: 如下图的一张关系图
a->b->c->d 如果a想给d送礼,则b,c都必须给d送礼,否则矛盾。
证明:若a给d送,b给c送,表中 b 必须找到的第一个祖先是 c 才能给 c送礼,所以 c 在表中应该比 d 靠前,这时候 a 找到的第一个祖先应该是 c ,
则 a 也应该给 c 送礼,和条件矛盾,得证。
第二个结论,如果存在这样一张表,则表中只有想给自己送礼的人。因为一个人给他的祖先送礼,则他祖先的所有子孙都要给他祖先送礼(上面的第一个结论)
那么我们只需要保存祖先即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <algorithm> 6 #include <cstring> 7 #include <stack> 8 #include <cctype> 9 #include <queue> 10 #include <string> 11 #include <vector> 12 #include <set> 13 #include <map> 14 #include <climits> 15 #define lson root<<1,l,mid 16 #define rson root<<1|1,mid+1,r 17 #define fi first 18 #define se second 19 #define ping(x,y) ((x-y)*(x-y)) 20 #define mst(x,y) memset(x,y,sizeof(x)) 21 #define mcp(x,y) memcpy(x,y,sizeof(y)) 22 using namespace std; 23 #define gamma 0.5772156649015328606065120 24 #define MOD 1000000007 25 #define inf 0x3f3f3f3f 26 #define N 100005 27 #define maxn 1005 28 typedef pair<int,int> PII; 29 typedef long long LL; 30 31 int a[N]; 32 int in[N],ans[N],cnt; 33 int n,m,k; 34 struct Node{ 35 int to,next; 36 }node[N]; 37 int head[N],hcnt; 38 inline void add(int x,int y){ 39 node[hcnt].to=y;node[hcnt].next=head[x]; 40 head[x]=hcnt++;++in[y]; 41 } 42 void dfs(int x){ 43 for(int i=head[x];~i;i=node[i].next){ 44 int e=node[i].to; 45 dfs(e); 46 if(a[e]!=e&&a[x]!=a[e]){ 47 exit(0*printf("-1\n")); 48 } 49 } 50 if(a[x]==x){ans[cnt++]=x;} 51 } 52 int main(){ 53 int i,j,group,x,y; 54 mst(head,-1);hcnt=0; 55 scanf("%d%d",&n,&m); 56 for(i=1;i<=m;++i){ 57 scanf("%d%d",&x,&y); 58 add(x,y); 59 } 60 for(i=1;i<=n;++i){scanf("%d",&a[i]);} 61 for(i=1;i<=n;++i){ 62 if(!in[i])dfs(i); 63 } 64 printf("%d\n",cnt); 65 for(i=0;i<cnt;++i) 66 printf("%d\n",ans[i]); 67 return 0; 68 }
codeforces 681D(Gifts by the List)
标签:
原文地址:http://www.cnblogs.com/Kurokey/p/5597142.html