参考链接
题意:n个王子和n个美女要进行配对,每个王子可以喜欢若干个美女,但只能匹配其一个美女,求解每个王子能配对的美女使得其他王子也能成功配对,按升序输出王子能匹配的美女的编号。数据已经给出一个完备匹配。
建图:王子到每个喜欢的美女连一条有向边,在给出的完备匹配中由美女到王子连接一条有向边。构图后简化一下描述就是:如果从 A 点出发,最终能回到 A 点(成环)则能够维持完全匹配的,因此求一次强连通分量,判断每个王子与其喜欢的美女是否在同一强连通分量即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<stack> 9 using namespace std; 10 #define N 5005 11 vector<int> g[N]; 12 stack<int> st; 13 int dfn[N],low[N],belg[N],in[N]; 14 int c,indx; 15 void init(){ 16 c=indx=1; 17 memset(dfn,0,sizeof(dfn)); 18 memset(low,0,sizeof(low)); 19 memset(belg,0,sizeof(belg)); 20 memset(in,0,sizeof(in)); 21 memset(g,0,sizeof(g)); 22 } 23 void dfs(int u){ 24 dfn[u]=low[u]=indx++; 25 in[u]=1; 26 st.push(u); 27 for(int i=0;i<g[u].size();i++){ 28 int v=g[u][i]; 29 if(!dfn[v]){ 30 dfs(v); 31 low[u]=min(low[u],low[v]); 32 } 33 else if(in[v]){ 34 low[u]=min(low[u],dfn[v]); 35 } 36 } 37 if(low[u]==dfn[u]){ 38 while(1){ 39 int v=st.top(); 40 st.pop(); 41 in[v]=0; 42 belg[v]=c; 43 if(v==u)break; 44 } 45 c++; 46 } 47 } 48 int main(){ 49 int n; 50 while(scanf("%d",&n)!=EOF){ 51 init(); 52 for(int i=1;i<=n;i++){ 53 int m; 54 scanf("%d",&m); 55 while(m--){ 56 int x; 57 scanf("%d",&x); 58 g[i].push_back(x+n); 59 } 60 } 61 for(int i=1;i<=n;i++){ 62 int x; 63 scanf("%d",&x); 64 g[x+n].push_back(i); 65 } 66 for(int i=1;i<=n;i++){ 67 if(!dfn[i])dfs(i); 68 } 69 for(int i=1;i<=n;i++){ 70 priority_queue<int ,vector<int> ,greater<int> > q; 71 for(int j=0;j<g[i].size();j++){ 72 int v=g[i][j]; 73 if(belg[i]==belg[v])q.push(v-n); 74 } 75 printf("%d",q.size()); 76 while(!q.empty()){ 77 printf(" %d",q.top()); 78 q.pop(); 79 } 80 printf("\n"); 81 } 82 } 83 return 0; 84 }