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 }