强连通分量,看大神的题解才会写的....

http://www.cnblogs.com/kuangbin/p/3261157.html

数据量有点大,第一次Submit 2995ms过的,时限3000ms,差一点就TLE了。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std; const int maxn = + ;
int N, M;
vector<int>Cun[maxn];
vector<int>G[maxn];
vector<int>FG[maxn];
int nx, ny, Time, Block;
int g[maxn][maxn];
int cx[maxn], cy[maxn];
int mk[maxn];
int flag[maxn], dfn[maxn], Belong[maxn];
struct Point
{
int id, dfn;
} point[maxn]; int Scan()
{
int res = , ch, flag = ; if ((ch = getchar()) == '-') //判断正负
flag = ; else if (ch >= '' && ch <= '') //得到完整的数
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + ch - ''; return flag ? -res : res;
} bool cmp(const Point&a, const Point&b)
{
return a.dfn>b.dfn;
} int path(int u)
{
for (int v = ; v <= ny; v++)
{
if (g[u][v] && !mk[v])
{
mk[v] = ;
if (cy[v] == - || path(cy[v]))
{
cx[u] = v;
cy[v] = u;
return ;
}
}
}
return ;
} int MaxMatch()
{
int res = ;
memset(cx, -, sizeof(cx));
memset(cy, -, sizeof(cy));
for (int i = ; i <= nx; i++)
{
if (cx[i] == -)
{
memset(mk, , sizeof(mk));
res = res + path(i);
}
}
return res;
} void dfs(int now)
{
flag[now] = ;
for (int i = ; i<G[now].size(); i++)
if (!flag[G[now][i]])
dfs(G[now][i]);
Time++;
dfn[now] = Time;
} void Dfs(int now)
{
Belong[now] = Block;
for (int i = ; i<FG[now].size(); i++)
if (!Belong[FG[now][i]])
Dfs(FG[now][i]);
} int main()
{
int CA;
CA = Scan();
for (int er = ; er <= CA; er++){
N = Scan();
M = Scan();
memset(flag, , sizeof(flag));
memset(dfn, , sizeof(dfn));
memset(Belong, , sizeof(Belong));
Time = , Block = ;
for (int i = ; i<maxn; i++) G[i].clear();
for (int i = ; i<maxn; i++) Cun[i].clear();
for (int i = ; i<maxn; i++) FG[i].clear();
memset(g, , sizeof(g));
nx = N, ny = M; for (int i = ; i <= N; i++)
{
int ToT, To;
ToT = Scan();
while (ToT--)
{
To = Scan();
Cun[i].push_back(To);
g[i][To] = ;
}
sort(Cun[i].begin(), Cun[i].end());
}
int res = MaxMatch(); memset(g, , sizeof(g));
int A = M - res, B = N - res;//A表示虚拟王子数量,B表示虚拟妹子数量
nx = N + A, ny = M + B;
if (B>)//王子有单身
{
for (int j = M + ; j <= M + B; j++)
for (int i = ; i <= N; i++)
{
g[i][j] = ;
G[i].push_back(j + nx);
FG[j + nx].push_back(i);
}
}
if (A>)
{
for (int i = N + ; i <= N + A; i++)
for (int j = ; j <= M; j++)
{
g[i][j] = ;
G[i].push_back(j + nx);
FG[j + nx].push_back(i);
}
}
for (int i = ; i <= N; i++)
for (int j = ; j<Cun[i].size(); j++)
{
g[i][Cun[i][j]] = ;
G[i].push_back(Cun[i][j] + nx);
FG[Cun[i][j] + nx].push_back(i);
}
MaxMatch();
for (int i = ; i <= ny; i++)
if (cy[i] != -)
{
G[i + nx].push_back(cy[i]);
FG[cy[i]].push_back(i + nx);
} for (int i = ; i <= nx + ny; i++) if (!dfn[i]) dfs(i);
for (int i = ; i<nx + ny; i++) point[i].id = i + , point[i].dfn = dfn[i + ];
sort(point, point + nx + ny, cmp);
for (int i = ; i<nx + ny; i++)
if (!Belong[point[i].id])
Block++, Dfs(point[i].id);
int RT;
int ans[maxn];
printf("Case #%d:\n", er);
for (int i = ; i <= N; i++)
{
RT = ;
for (int j = ; j<Cun[i].size(); j++)
{
if (Belong[i] == Belong[Cun[i][j] + nx])
{
ans[RT] = Cun[i][j];
RT++;
}
}
printf("%d", RT);
for (int x = ; x<RT; x++) printf(" %d", ans[x]);
printf("\n");
}
}
return ;
}

HDU 4685 Prince and Princess的更多相关文章

  1. HDU 4685 Prince and Princess 二分图匹配+tarjan

    Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...

  2. HDU 4685 Prince and Princess (2013多校8 1010题 二分匹配+强连通)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...

  4. hdu 4685 Prince and Princess(匈牙利算法 连通分量)

    看了别人的题解.须要用到匈牙利算法的强连通算法 #include<cstdio> #include<algorithm> #include<vector> #pra ...

  5. HDU 4685 Prince and Princess(二分匹配+强联通分量)

    题意:婚配问题,但是题目并不要求输出最大匹配值,而是让我们输出,一个王子可以与哪些王妃婚配而不影响最大匹配值. 解决办法:先求一次最大匹配,如果有两个已经匹配的王妃,喜欢她们两个的有两个或者以上相同的 ...

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

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  7. HDU4685:Prince and Princess(二分图匹配+tarjan)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

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

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  9. POJ 1904 HDU 4685

    这两道题差不多,POJ这道我很久以前就做过,但是比赛的时候居然没想起来.. POJ 这道题的题意是,N个王子每个人都有喜欢的公主,当他们选定一个公主结婚时,必须是的剩下的人也能找到他喜欢的公主结婚. ...

随机推荐

  1. tableviewcell滑动显示多个按钮UITableViewRowAction(转载)

    demo截图 ios8 新的属性 typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) { UITableViewRowActionStyleDe ...

  2. 不合法语句 self.contentView.frame.origin.x = x;

    下面的写法是错误的: CGFloat x = self.contentView.frame.origin.x; x = _lastDownX + translation.x; self.content ...

  3. power oj/2360/Change

    题目链接[https://www.oj.swust.edu.cn/problem/show/2360] 题意:给出两个四位数A.B,目地是用最少的步骤使A变成B.变换规则如下:1.相邻的两位数可以交换 ...

  4. linux内核驱动——从helloworld开始

    学习编程第一个都是学习hello world程序,学习内核驱动自然也不例外,我也是!本文整理了网上的一些资料以及加上自己的一些心得体会,希望对初学者有帮助,可别小看这个简单的hello world,本 ...

  5. caogao

    https://css-tricks.com/ 在safari浏览器中添加transform规则,如果没有效果,把该规则的原始元素以块状显示 http://webdesignerwall.com/tr ...

  6. iOS拨打电话

    1,这种方法,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出提示NSMutableString * str=[[NSMutableString alloc] initWithFo ...

  7. MFC连接Access讲解(3合1) .

    方法一: 1.首先,要用#import语句来引用支持ADO的组件类型库(*.tlb),其中类型库可以作为可执行程序(DLL.EXE等)的一部分被定位在其自身程序中的附属资源里,如:被定位在msado1 ...

  8. aspx中如何加入javascript

    Response.Write("<script>window.location ='aaa.aspx';</script>"); Response.Writ ...

  9. 求最大公约数(GCD)的两种算法

    之前一直只知道欧几里得辗转相除法,今天学习了一下另外一种.在处理大数时更优秀的算法--Stein 特此记载 1.欧几里得(Euclid)算法 又称辗转相除法,依据定理gcd(a,b)=gcd(b,a% ...

  10. Nmap的使用【转载】

    1.NMap工具 主要功能:探测主机是否在线.扫描主机开放端口和嗅探网络服务,用于网络探测和安全扫描. NMap支持很多扫描技术,例如:UDP.TCPconnect().TCPSYN(半开扫描).ft ...