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

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. 快速进入pycharm图形界面

    解压后的pycharm相关文件的路径:/home/hadoop2/下载/pycharm-community-4.5.4 添加快速启动pycharm命令: (1)进入/usr/local/sbin这个目 ...

  2. POJ1113 Wall 凸包

    题目大意:建立围墙将城堡围起来,要求围墙至少距离城堡L,拐角处用圆弧取代,求围墙的长度. 题目思路:围墙长度=凸包周长+(2*PI*L),另外不知道为什么C++poj会RE,G++就没问题. #inc ...

  3. elipse图标注解

    Java中的访问修饰符(访问控制符)包括:public,protected,default,private.分别代表了不同的访问权限.如果省略,则被视为使用了默认的default作为访问修饰符.从字面 ...

  4. spring框架--IOC容器,依赖注入

    思考: 1. 对象创建创建能否写死? 2. 对象创建细节 对象数量 action  多个   [维护成员变量] service 一个   [不需要维护公共变量] dao     一个   [不需要维护 ...

  5. 二、oracle sql*plus常用命令

    一.sys用户和system用户Oracle安装会自动的生成sys用户和system用户(1).sys用户是超级用户,具有最高权限,具有sysdba角色,有create database的权限,该用户 ...

  6. redis------del命令

    删除 可以删除给定的一个或多个key; set keyname1  name1 set keyname2 name2 set keyname3 name3 del  keyname1  keyname ...

  7. APK重新签名方法

    Android使用SHA1-RSA算法进行签名.可通过eclipse插件进行,可以通过keytool和jarsigner 用命令行执行,也可以在源码下进行签名. 第一种:通过使用eclipse进行签名 ...

  8. 用VBS控制鼠标的实现代码(获取鼠标坐标、鼠标移动、鼠标单击、鼠标双击)

    网上搜到的答案普遍是VBS无法实现,或者是要用第三方COM(ActiveX?)组件.我对第三方组件是很反感的,使用第三方组件毫无可移植性可言,因为别人的系统中不一定注册了这个组件.我的建议是,尽量不要 ...

  9. mysql读写分离配置,利用mybatis实现,解释为什么dynamicDataSource不行

    之前发布了mysql主从配置的博客,配置完成之后,那么我们肯定要拿主从来做点什么. 我第一想到的就是mysql的读写分离,让读写分离之后可以大大的提供mysql的性能,比单纯用mysql主从做备份好很 ...

  10. java编码问题

    工作中经常遇到java编码问题,由于缺乏研究,总是无法给出确切的答案,这个周末在网上查了一些资料,在此做些汇总. 问题一:在java中读取文件时应该采用什么编码? Java读取文件的方式总体可以分为两 ...