HDU 4685 Prince and Princess

Prince and Princess

Time Limit: 3000ms

Memory Limit: 32768KB

This problem will be judged on HDU. Original ID: 4685
64-bit integer IO format: %I64d      Java class name: Main

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 princess that can marry.
Now for each prince, your task is to output all the princesses he can marry. Of course if a prince wants to marry one of those princesses,the maximum number of marriage pairs of the rest princes and princesses cannot change.

Input

The first line of the input contains an integer T(T<=25) which means the number of test cases.
For each test case, the first line contains two integers n and m (1<=n,m<=500), means the number of prince and princess.
Then n lines for each prince contain the list of the princess he loves. Each line starts with a integer ki(0<=ki<=m), and then ki different integers, ranging from 1 to m denoting the princesses.

Output

For each test case, first output "Case #x:" in a line, where x indicates the case number between 1 and T.
Then output n lines. For each prince, first print li, the number of different princess he can marry so that the rest princes and princesses can still get the maximum marriage number.
After that print li different integers denoting those princesses,in ascending order.

Sample Input

2
4 4
2 1 2
2 1 2
2 2 3
2 3 4
1 2
2 1 2

Sample Output

Case #1:
2 1 2
2 1 2
1 3
1 4
Case #2:
2 1 2

Source

2013 Multi-University Training Contest 8

解题:完备匹配+强连通。至于求强连通,有两种建图方式。

方式一:把王子也作为图的顶点,建图,匹配边是从公主指向王子,非匹配边,王子指向公主,当然必须是喜欢的。

方式二:直接建立只包含公主的图进行求强连通,然后看与该王子已匹配的公主所在的强联通分量中,还有哪些是王子喜欢。喜欢的即可以互换?人妻互换???????好邪恶的样子!!!!!一个圈,转一圈,还是自己喜欢的另一个她。。。。。

我采用的是第二种方式建图的。。。

不过,有个地方要注意下,n与m不想等,所以,要创建虚拟女友跟虚拟男友了。。。。。不然怎么完备匹配。。。。

建立虚拟女友,每个王子都喜欢的

建立虚拟男友,喜欢每个公主。。。

他们之间的关系。。。。很复杂。。。。

此图貌似求最大匹配很费时,下次改成HK玩玩,啊哈,interesting啊!!!!!

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <climits>
  7 #include <vector>
  8 #include <queue>
  9 #include <cstdlib>
 10 #include <string>
 11 #include <set>
 12 #include <stack>
 13 #define LL long long
 14 #define pii pair<int,int>
 15 #define INF 0x3f3f3f3f
 16 using namespace std;
 17 const int maxn = 50000;
 18 struct arc {
 19     int to,next;
 20     arc(int x = 0,int y = -1) {
 21         to = x;
 22         next = y;
 23     }
 24 };
 25 arc e[500000];
 26 int head[maxn],dfn[maxn],low[maxn],belong[maxn];
 27 int tot,nx,ny,top,scc,idx,lx[maxn],ly[maxn],mystack[maxn];
 28 bool mp[1000][1000],instack[maxn],vis[maxn];
 29 void add(int u,int v) {
 30     e[tot] = arc(v,head[u]);
 31     head[u] = tot++;
 32 }
 33 bool dfs(int u) {
 34     for(int i = 1; i <= ny; ++i) {
 35         if(mp[u][i]&&!vis[i]) {
 36             vis[i] = true;
 37             if(ly[i] == -1 || dfs(ly[i])) {
 38                 ly[i] = u;
 39                 lx[u] = i;
 40                 return true;
 41             }
 42         }
 43     }
 44     return false;
 45 }
 46 int hungry() {
 47     memset(lx,-1,sizeof(lx));
 48     memset(ly,-1,sizeof(ly));
 49     int ans = 0;
 50     for(int i = 1; i <= nx; ++i) {
 51         memset(vis,false,sizeof(vis));
 52         ans += dfs(i);
 53     }
 54     return ans;
 55 }
 56 void tarjan(int u) {
 57     dfn[u] = low[u] = ++idx;
 58     instack[u] = true;
 59     mystack[top++] = u;
 60     for(int i = head[u]; ~i; i = e[i].next) {
 61         if(!dfn[e[i].to]) {
 62             tarjan(e[i].to);
 63             low[u] = min(low[u],low[e[i].to]);
 64         } else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]);
 65     }
 66     if(dfn[u] == low[u]) {
 67         int v;
 68         scc++;
 69         do {
 70             v = mystack[--top];
 71             instack[v] = false;
 72             belong[v] = scc;
 73         } while(v != u);
 74     }
 75 }
 76 void init() {
 77     for(int i = 0; i < maxn; ++i) {
 78         dfn[i] = low[i] = belong[i] = 0;
 79         instack[i] = false;
 80         head[i] = -1;
 81     }
 82     tot = scc = idx = top = 0;
 83     memset(mp,false,sizeof(mp));
 84 }
 85 int main() {
 86     int T,cs = 1,n,m,k,u,v;
 87     scanf("%d",&T);
 88     while(T--) {
 89         scanf("%d %d",&n,&m);
 90         nx = n;
 91         ny = m;
 92         init();
 93         for(int i = 1; i <= n; ++i) {
 94             scanf("%d",&k);
 95             while(k--) {
 96                 scanf("%d",&v);
 97                 mp[i][v] = true;
 98             }
 99         }
100         nx = ny = n + m - hungry();
101         for(int i = n+1; i <= nx; ++i)
102             for(int j = 1; j <= ny; ++j)
103                 mp[i][j] = true;//建立虚拟王子
104         for(int i = m+1; i <= ny; ++i)
105             for(int j = 1; j <= nx; ++j)
106                 mp[j][i] = true;//建立虚拟公主
107         hungry();
108         for(int i = 1; i <= nx; ++i) {
109             for(int j = 1; j <= ny; ++j)
110                 if(mp[i][j] && lx[i] != j)  add(lx[i],j);
111         }
112         for(int i = 1; i <= nx; ++i)
113             if(!dfn[i]) tarjan(i);
114         printf("Case #%d:\n",cs++);
115         vector<int>ans;
116         for(int i = 1; i <= n; ++i) {
117             ans.clear();
118             for(int j = m; j >= 0; --j)
119                 if(mp[i][j]&& belong[lx[i]] == belong[j]) ans.push_back(j);
120             printf("%d",ans.size());
121             for(int j = ans.size()-1; j >= 0; --j)
122                 printf(" %d",ans[j]);
123             putchar(‘\n‘);
124         }
125     }
126     return 0;
127 }

时间: 2024-10-10 07:44:41

HDU 4685 Prince and Princess的相关文章

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

Prince and Princess HDU - 4685(匹配 + 强连通)

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

Prince and Princess

hdu4685:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚公主就比较悲惨, 跟谁结婚都行,然后输出王子可能的结婚对象. 题解:这一题看了题解之后,也还是只知道是怎么做的,至于为什么那么做还是不懂啊. 解题步奏:首先让王子和喜欢的人之间建立一条边,然后,求一个最大匹配res,然后左边王子加入m-res个虚拟王子,右边加入n-res虚拟公主,所以新加入的王子喜欢

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) 第一次

算法竞赛与入门经典---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

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 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