King's Quest

poj1904:http://poj.org/problem?id=1904

题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配,匹配有n个数,代表某个儿子和哪个女孩可以结婚,已知这些条件,要你找出每个儿子可以和哪些女孩结婚

题解:首先儿子和喜欢女孩建一条边,然后最后的女孩和儿子建一条边,然后缩点就可以了,至于为什么这么做,还在研究当中。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<set>
 7 using namespace std;
 8 vector<int>ans;
 9 const int N=4000+30;
10 const int M=400010;
11 const int INF=0xffffffff;
12 struct Edge{
13     int to,next;
14 } edge[M];
15 int  n,m,temp,cnt,dep,top,atype;
16 int  dfn[N],low[N],vis[N],head[N],st[N],belong[N],in[N],out[N],sum[N];
17 //sum[i]记录第i个连通图的点的个数,in[i],out[i],表示缩点之后点的入度和初度。
18 void init(){
19       cnt=dep=top=atype=0;
20     memset(head,-1,sizeof(head));
21     memset(dfn,0,sizeof(dfn));
22     memset(low,0,sizeof(low));
23     memset(vis,0,sizeof(vis));
24     memset(belong,0,sizeof(belong));
25     memset(in,0,sizeof(in));
26     memset(out,0,sizeof(out));
27     memset(sum,0,sizeof(sum));
28 }
29 void addedge(int u,int v){
30     edge[cnt].to=v;
31     edge[cnt].next=head[u];
32     head[u]=cnt++;
33 }
34
35 void Tarjan(int u){
36     dfn[u]=low[u]=++dep;
37     st[top++]=u;
38     vis[u]=1;
39     for(int i=head[u]; i!=-1; i=edge[i].next){
40         int v=edge[i].to;
41         if(!dfn[v]){
42             Tarjan(v);
43             low[u]=min(low[u],low[v]);
44         }
45         else if(vis[v]){
46             low[u]=min(low[u],dfn[v]);
47         }
48     }
49     int j;
50     if(dfn[u]==low[u]){
51         atype++;
52         do{
53             j=st[--top];
54             belong[j]=atype;
55             sum[atype]++;   //记录每个连通分量中点的个数
56             vis[j]=0;
57         }
58         while(u!=j);
59     }
60 }
61 int main(){
62      while(~scanf("%d",&n)){
63         init();
64         for(int i=1;i<=n;i++){
65             scanf("%d",&m);
66             for(int j=1;j<=m;j++){
67                 scanf("%d",&temp);
68                 addedge(i,temp+n);
69             }
70         }
71         for(int i=1;i<=n;i++){
72             scanf("%d",&temp);
73             addedge(temp+n,i);
74         }
75         for(int i=1;i<=2*n;i++)
76             if(!dfn[i])
77             Tarjan(i);
78         for(int i=1;i<=n;i++){
79             ans.clear();
80             for(int j=head[i];j!=-1;j=edge[j].next){
81                 int v=edge[j].to;
82             if(belong[i]==belong[v])
83                 ans.push_back(v-n);
84             }
85             int sz=ans.size();
86             sort(ans.begin(),ans.end());
87             printf("%d",sz);
88             for(int j=0;j<sz;j++){
89                 printf(" %d",ans[j]);
90             }
91             puts("");
92         }
93      }
94 }

King's Quest

时间: 2024-10-01 11:51:52

King's Quest的相关文章

POJ1904 King&#39;s Quest(完备匹配可行边:强连通分量)

题目大概就是说给一张二分图以及它的一个完备匹配,现在问X部的各个点可以与Y部那些些点匹配,使得X部其余点都能找到完备匹配. 枚举然后匹配,当然不行,会超时. 这题的解法是,在二分图基础上建一个有向图:原二分图中边(x,y)连<x,y>的弧,对于那个已知的匹配中的所有边(x,y)连<y,x>的弧,然后对于X部各个点x如果它到Y部的y点有直接的边且它们在同一个强连通分量,那么x就能和y匹配. 我对这个解法的理解是这样的,类似于匈牙利算法的增广路: 如果x和y就属于给定的那个完备匹配那它

poj 1904 King&#39;s Quest

King's Quest 题意:有N个王子和N个妹子;(1 <= N <= 2000)第i个王子喜欢Ki个妹子:(详见sample)题给一个完美匹配,即每一个王子和喜欢的一个妹子结婚:问每一个王子可以有几种选择(在自己喜欢的妹子里面选),并输出可选的妹子的标号(升序): Sample Input 4 (N) 2 1 2 (Ki) 2 1 2 2 2 3 2 3 4 1 2 3 4 (完美匹配) Sample Output 2 1 2 2 1 2 1 3 1 4 分析:图匹配问题,1~N为王子的

POJ 1904:King&#39;s Quest【tarjan】

题目大意:给出一个二分图的完美匹配(王子和公主的烧死名单表),二分图x部和y部均只有n个点,问对于每一个x部的点,他能选择哪些点与之匹配 使得与之匹配后,剩余图的最大匹配仍然是n 思路:这题是大白书379页二分图的压轴题,在图论刷的题还不多时思考过这题,现在想来也不难想 这题引人瞩目的一点便是预先给出了一个二分图的初始匹配 对每个点枚举后增广显然不怎么可行,那么还是图论问题的经典思考方式,点和边各表示什么 题目的输入天然的给出了一个图,但对这题好像没什么用处,于是开始思考把给出的初始匹配的每条边

Poj 1904 King&#39;s Quest 强连通分量

题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可以取哪些公主,并且保证取了一个公主后,全局还是存在完美匹配. 题解: 1.建图: 如果王子u对公主v心仪,则连一条边u->v.在样例给出的那组完美匹配中,如果王子u娶了公主v,连一条边v->u. 2.求强连通分量: 如果王子和自己心仪的公主属于同一个强连通分量,那么王子就可以娶这个公主. 1 #i

POJ - 1904 King&#39;s Quest(强连通分量+二分图匹配)

题目大意:有N个帅哥和N个美女,现在给出每个帅哥所喜欢的美女的编号,和一个帅哥和美女的完美匹配 问每个帅哥可以娶多少个美女,且当他娶完这个美女后,剩下的人还可以完美匹配 解题思路:神题啊,给一个大神的详细解答 具体是这样的,首先先建边,把帅哥和能娶到的美女连边,再把完美匹配的美女和帅哥连边,这样就形成了一张有向图了 接着,找出这张有向图的所有强连通分量,在强连通分量里面的帅哥都可以娶到自己喜欢的美女,且娶完这个美女后,不会影响到其他人 为什么呢? 假设xi为帅哥,yi和yj为美女,假设给定的完美

POJ 1904 King&#39;s Quest 强连通分量+二分图增广判定

http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <stack> #include <ve

UVALive-2966 King&#39;s Quest(强连通+二分图匹配)

题目大意:有n个男孩和和n个女孩,已只每个男孩喜欢的女孩.一个男孩只能娶一个女孩.一个女孩只能嫁一个男孩并且男孩只娶自己喜欢的女孩,现在已知一种他们的结婚方案,现在要求找出每个男孩可以娶的女孩(娶完之后不能影响其他男孩结婚). 题目分析:已知的结婚方案是一个完全匹配.从每个男孩出发向他喜欢的女孩连一条有向边,得到一张完全二分图,实际上这道题是让判断去掉哪一些边使图仍然完全匹配.设男生x1和女生y1是已知方案中要结婚的两个人,假如x1抛弃y1,选择了他也喜欢的y2结婚(也就是去掉边x1->y2),

King&#39;s Quest - poj 1904(强连通分量+外挂输入输出)

题意:国王有N个儿子,每个儿子都有很多喜欢的姑娘,官员为每个王子都找了一个姑娘让他们结婚,不过国王不满意,他想知道他的每个儿子都可以和那个姑娘结婚(前提他的儿子必须喜欢那个姑娘) 分析:因为最下面一行已经给出来每个王子可以结婚的对象了,所以就不必在去求完备匹配了,直接加入反边求出来环就行了,不过注意环中的姑娘未必是王子喜欢的对象,需要再次判断一下才行.ps.第一次知道有输出输入外挂这东西,不过优化的确实很给力. ******************************************

【建模+强连通分量】POJ1904 King&#39;s Quest

Description 一个国王有n个王子,同时有n个女孩.每个王子都有自己喜欢的若干个女孩,现给定一个合法的完备匹配(也就是一个王子娶其中一个自己喜欢女孩),求每个王子可以选择哪些女孩可以让剩下的每个王子依旧能够选择到自己喜欢的一个女孩. Solution 对于给定的排列,我们设ai为男a对应的女生,bi为女b对应的男生. 男i可以选哪些女生?选ai显然是可以的,如果没有选ai而选的x,那么会造成两个影响,x有两个a和bx选,ai没有人选. 所以需要让bx选新的女生,如果bx能选到ai,那么问

POJ 1904 King&#39;s Quest(强连通)

POJ 1904 King's Quest 题目链接 题意:n个男人,每个人都有一个喜欢的女人列表,现在给一个完美匹配,问所有完美匹配中,每个人可能娶到的女人列表 思路:强连通,建图,男的连一条边指向女,然后完美匹配的边女的指向男,然后求强连通,在同一个强连通分支并且是自己想娶的的就可能娶到 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #inc