首页 > 代码库 > HDU 4685 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: 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

24 42 1 22 1 22 2 32 3 41 22 1 2

Sample Output

Case #1:2 1 22 1 21 31 4Case #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 }
View Code

 

HDU 4685 Prince and Princess