标签:
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1267 Accepted Submission(s): 358
题意:一个王国里有n个王子和m个公主,公主可以跟任何王子结婚,但是王子可以选择和他喜欢的公主结婚,喜欢的公主可以有多个,但是最终只能选择其中一个结婚,公主一样也必须只能和一个王子结婚,现在给出n和m,接下来n行,第i行首先有个数ki,然后k个数,代表第i个王子喜欢的公主编号,接下来输出n行,表示每个王子可以有多少公主可以选择,并从小大输出公主标号,并保证这些选择不会有冲突,且满足最大匹配
程序:
#include"cstdio" #include"cstring" #include"cstdlib" #include"cmath" #include"string" #include"map" #include"cstring" #include"iostream" #include"algorithm" #include"queue" #include"stack" #define inf 0x3f3f3f3f #define M 10009 #define eps 1e-8 #define INT int #define LL __int64 using namespace std; struct node { int u,v,next; }edge[300009]; int cmp(int a,int b) { return a<b; } int h[M]; int x[M]; int y[M]; int head[M]; int dfn[M]; int belong[M]; int low[M]; int use[M]; int sum[M]; int in[M]; int out[M]; int t,indx,num,m,n; stack<int>q; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v) { edge[t].u=u; edge[t].v=v; edge[t].next=head[u]; head[u]=t++; } int finde(int u) { for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].v; if(!use[v]) { use[v]=1; if(!y[v]||finde(y[v])) { use[v]=1; y[v]=u; x[u]=v; return 1; } } } return 0; } void tarjan(int u,int id) { dfn[u]=low[u]=++indx; q.push(u); use[u]=1; for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].v; if(!dfn[v]) { tarjan(v,i); low[u]=min(low[u],low[v]); } else if(use[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { int p; num++; do { p=q.top(); q.pop(); use[p]=0; belong[p]=num; sum[num]++; }while(p!=u); } } int match(int nl) { memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); int ans=0; for(int i=1;i<=nl;i++) { if(!x[i]) { memset(use,0,sizeof(use)); ans+=finde(i); } } return ans; } void slove() { int cnt=match(n); int all=m+n-cnt; for(int i=n+1;i<=all;i++) { for(int j=1;j<=all;j++) add(i,j+1000); } for(int i=1;i<=all;i++) { for(int j=m+1;j<=all;j++) { //if(x[i]==0) add(i,j+1000); } } match(all); for(int i=1;i<=all;i++) { if(x[i]) add(x[i],i); } num=indx=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(use,0,sizeof(use)); memset(sum,0,sizeof(sum)); for(int i=1;i<=all;i++) { if(!dfn[i]) { tarjan(i,-1); } } for(int u=1;u<=n;u++) { int fuck=0; for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].v; if(v>n&&belong[u]==belong[v]&&v<=1000+m) h[fuck++]=v-1000; } sort(h,h+fuck,cmp); printf("%d",fuck); for(int i=0;i<fuck;i++) printf(" %d",h[i]); printf("\n"); } } int main() { int T,kk=1; cin>>T; while(T--) { scanf("%d%d",&n,&m); init(); for(int i=1;i<=n;i++) { int k,j; scanf("%d",&k); while(k--) { scanf("%d",&j); add(i,1000+j); } } printf("Case #%d:\n",kk++); slove(); } }
强连通+二分匹配(hdu4685 Prince and Princess)
标签:
原文地址:http://www.cnblogs.com/mypsq/p/4485609.html