Prince and Princess

hdu4685:http://acm.hdu.edu.cn/showproblem.php?pid=4685

题意:有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚公主就比较悲惨, 跟谁结婚都行,然后输出王子可能的结婚对象。

题解:这一题看了题解之后,也还是只知道是怎么做的,至于为什么那么做还是不懂啊。

解题步奏:首先让王子和喜欢的人之间建立一条边,然后,求一个最大匹配res,然后左边王子加入m-res个虚拟王子,右边加入n-res虚拟公主,所以新加入的王子喜欢所有的公主,所有加入的公主被所有的王子喜欢,然后再跑最大匹配。如果,对于第i个王子,把他喜欢的公主,然后建立一条边,然后缩点,在同一个连通块中的是可以交换的(这里不是很理解)。然后输出。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 const int N=1002;
  8 const int M=400010;
  9 const int INF=0xffffffff;
 10 int  n,m,u,cnt,dep,top,atype,newn,newm;
 11 int  dfn[N],low[N],vis[N],head[N],st[N],belong[N],lx[N],cy[N];
 12 bool visit[N],g[N][N];
 13 vector<int>ans;
 14 int path(int u){
 15      for(int i=1;i<=newm;i++){
 16         if(!visit[i]&&g[u][i]){
 17             visit[i]=1;
 18         if(cy[i]==-1||path(cy[i])){
 19             cy[i]=u;
 20             return 1;
 21         }
 22        }
 23      }
 24    return 0;
 25 }
 26 int maxmatch(){
 27     memset(cy,-1,sizeof(cy));
 28     int res=0;
 29     for(int i=1;i<=newn;i++){
 30     memset(visit,0,sizeof(visit));
 31         res+=path(i);
 32     }
 33     return res;
 34 }
 35 struct Edge{
 36     int to,next;
 37 } edge[M];
 38 void init(){
 39       cnt=dep=top=atype=0;
 40     memset(head,-1,sizeof(head));
 41     memset(dfn,0,sizeof(dfn));
 42     memset(low,0,sizeof(low));
 43     memset(vis,0,sizeof(vis));
 44     memset(belong,0,sizeof(belong));
 45     memset(g,0,sizeof(g));
 46 }
 47 void addedge(int u,int v){
 48     edge[cnt].to=v;
 49     edge[cnt].next=head[u];
 50     head[u]=cnt++;
 51 }
 52
 53 void Tarjan(int u){
 54     dfn[u]=low[u]=++dep;
 55     st[top++]=u;
 56     vis[u]=1;
 57     for(int i=head[u]; i!=-1; i=edge[i].next){
 58         int v=edge[i].to;
 59         if(!dfn[v]){
 60             Tarjan(v);
 61             low[u]=min(low[u],low[v]);
 62         }
 63         else if(vis[v]){
 64             low[u]=min(low[u],dfn[v]);
 65         }
 66     }
 67     int j;
 68     if(dfn[u]==low[u]){
 69         atype++;
 70         do{
 71             j=st[--top];
 72             belong[j]=atype;
 73             vis[j]=0;
 74         }
 75         while(u!=j);
 76     }
 77 }
 78 int cas;
 79 int main(){
 80    scanf("%d",&cas);
 81    int tt=1;
 82    while(cas--){
 83       scanf("%d%d",&n,&m);
 84       init();
 85       for(int i=1;i<=n;i++){
 86           int temp;
 87           scanf("%d",&temp);
 88           for(int j=1;j<=temp;j++){
 89             scanf("%d",&u);
 90             g[i][u]=1;
 91           }
 92       }
 93         newn=n;newm=m;
 94       int ans1=maxmatch();
 95        newn=n+m-ans1;
 96        newm=n+m-ans1;
 97       for(int i=n+1;i<=newn;i++){
 98           for(int j=1;j<=newm;j++)
 99               g[i][j]=1;
100       }
101       for(int i=1;i<=newn;i++){
102           for(int j=1+m;j<=newm;j++)
103               g[i][j]=1;
104       }
105         maxmatch();
106         memset(lx,-1,sizeof(lx));
107       for(int i=1;i<=newm;i++){
108           if(cy[i]!=-1)
109             lx[cy[i]]=i;
110       }
111       for(int i=1;i<=newn;i++){
112         for(int j=1;j<=newm;j++){
113             if(g[i][j]&&j!=lx[i])
114                 addedge(lx[i],j);
115         }
116       }
117         for(int i=1;i<=newm;i++)
118             if(!dfn[i])
119               Tarjan(i);
120         printf("Case #%d:\n",tt++);
121         for(int i=1;i<=n;i++){
122             ans.clear();
123             for(int j = 1; j <= m;j++)
124                 if(g[i][j] && belong[j] == belong[lx[i]])
125                     ans.push_back(j);
126             int sz = ans.size();
127             printf("%d",sz);
128             for(int i = 0;i < sz;i++)
129                 printf(" %d",ans[i]);
130             printf("\n");
131         }
132    }
133 }

Prince and Princess

时间: 2024-07-31 18:29:27

Prince and Princess的相关文章

HDU 4685 Prince and Princess

Prince and Princess Time Limit: 3000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 468564-bit integer IO format: %I64d      Java class name: Main There are n princes and m princesses. Princess can marry any prince. But prin

算法竞赛与入门经典---P66 [UVA 10635] Prince and Princess

Prince and PrincessInput: Standard Input Output: Standard Output Time Limit: 3 Seconds In an n x n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered 1, 2, 3 ... n*n, as shown below: Prince stands in square 1, ma

uva10635 Prince and Princess LCS 变 lIS

// uva10635 Prince and Princess LCS 变 lIS // 本意求LCS,但是规模有60000多,复杂度肯定不够 // 注意如果俩个序列的值的范围相同,那么可以在一个 // 串中记录在另外一个串中的位置.这样就可以转化成 // 最长上升子序列的问题啦,复杂度是nlogn,可以ac // 这题,还是挺有考究的价值的,很不错 // 哎,继续练吧..... #include <algorithm> #include <bitset> #include <

UVA10635 Prince and Princess(LIS)

题意:王子和公主同时从1出发走到 n*n, 求他们两个路径的最长公共子序列: 思路:因为这题n有250,如果用LCS负责度为O(n^2),容易超时,于是我们选择它的优化版Lis算法来求最长公共子序列,这样我们的复杂度就降为O(n*logn)了. Lis算法: 先回顾经典的O(n^2)的动态规划算法,设A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设F[t] = 0(t = 1, 2, ..., len(A)).则有动态规划方程:F[t] = ma

HDU 4685 Prince and Princess(二分图 + 强连通)

Problem Description There are n princes and m princesses. Princess can marry any prince. But prince can only marry the princess they DO love. For all princes,give all the princesses that they love. So, there is a maximum number of pairs of prince and

uva 10635 Prince and Princess(DP)

uva 10635 Prince and Princess(DP) In an n x n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered 1, 2, 3 ... n*n, as shown below: Prince stands in square 1, make p jumps and finally reach square n*n. He enters a

UVa 10635 (LIS+二分) Prince and Princess

题目的本意是求LCS,但由于每个序列的元素各不相同,所以将A序列重新编号{1,2,,,p+1},将B序列重新编号,分别为B中的元素在A中对应出现的位置(没有的话就是0). 在样例中就是A = {1 7 5 4 8 3 9},B = {1 4 3 5 6 2 8 9} 重新编号以后: A = {1 2 3 4 5 6 7}, B = {1 4 6 3 0 0 5 7}(里面的0在求LIS时可以忽略) 这样求A.B的LCS就转变为求B的LIS 求LIS用二分优化,时间复杂度为O(nlogn) 第一次

uva 10635 Prince and Princess(LCS问题转化成LIS问题O(nlogn))

题目大意:有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n^2之间的整数.两个序列的第一个元素均为1.求出A和B的最长公共子序列长度. 分析:本题是LCS问题,但是p*q<=62500,O(pq)的算法显然会LE.在这里有一个条件,每个序列中的各个元素互不相同,所以可以把A中元素重新编号为1~p+1.例如,样例中A={1,7,5,4,8,3,9},B={1,4,3,5,6,2,8,9},因此把A重新编号为{1,2,3,4,5,6,7},则B就是{1,4,6,3,0

强连通+二分匹配(hdu4685 Prince and Princess)

Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1267    Accepted Submission(s): 358 Problem Description There are n princes and m princesses. Princess can marry any prince. B