King's Quest POJ - 1904 匈牙利算法的思想+tarjan缩点+染色
题目链接:https://cn.vjudge.net/problem/POJ-1904
自己一开始的想法,打算用匈牙利算法实现,找二分图的最大匹配。但是打了打发现,不太好实现。原因如下:匈牙利算法是不停的找增广路。如果这个题用匈牙利算法实现的时候,就是这个地方:
bool Find(int t)
{
for(int i=; i<=m; i++)
{
if(line[t][i]&&Exit[i]==)
{
Exit[i]=;
if(net[i]==||Find(net[i]))
{
net[i]=t;
return true;
}
}
}
}
,这个是找到合法的就返回,无法把所有的情况都找到,所以这个方法不行。
然后再去想tarjan算法,找缩点,也就是图上的两点都能都到达,如果是王子向喜欢的公主连线的话,连一条单向边,如果是公主喜欢的王子的话,然后再从公主连向王子一条单向边,这样,就能够在最大匹配的图上实现一个连通图的建立.
但是注意这个题有个坑点,在构成连通图的时候,有的王子不喜欢某个公主,但是在图上也有可能通过别的点联通起来,这个时候就需要特判一下了。
AC代码:
#include<iostream>
#include<stack>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stdio.h>
#include<map>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
const int N = + ;
const int M = + ;
struct node
{
int to;
int nex;
} edge[M];
int head[M],low[N],dfn[N],istack[N];
int num,ind,col,n,m;
stack<int>q;
vector<int>wakaka[N];
vector<int>w1;
vector<int>ans[N];
int Map[][];
void init()
{
while(!q.empty())q.pop();
memset(head,-,sizeof(head));
num=,ind=,col=;
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(istack,,sizeof(istack));
}
void addedge(int fr,int to)
{
edge[num].to=to;
edge[num].nex=head[fr];
head[fr]=num++;
}
void tarjan(int u,int root)
{
q.push(u);
low[u]=dfn[u]=++ind;
for(int i=head[u]; i!=-; i=edge[i].nex)
{
int v=edge[i].to;
if(dfn[v]==)
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else if(istack[v]==)
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
int t;
col++;
do
{
t=q.top();
q.pop();
istack[t]=col;
wakaka[col].push_back(t);
}
while(t!=u);
}
}
int main()
{
init();
scanf("%d",&n);
int t;
for(int i=; i<=n; i++)
{
scanf("%d",&m);
for(int j=; j<=m; j++)
{
scanf("%d",&t);
addedge(i,t+n);
Map[i][t]=;
}
}
for(int i=; i<=n; i++)
{
scanf("%d",&t);
addedge(t+n,i);
// Map[t][i]=1;
}
for(int i=; i<=n; i++)
{
if(dfn[i]==)
{
tarjan(i,);
}
}
for(int i=; i<=col; i++)
{
sort(wakaka[i].begin(),wakaka[i].end());
int len=wakaka[i].size();
for(int j=; j<len; j++)
{
int u=wakaka[i][j];
if(u<=n)w1.push_back(u);
else
{
int len2=w1.size();
for(int k=; k<len2; k++)
{
if(Map[w1[k]][u-n])//判断是不是有相互喜欢的关系
ans[w1[k]].push_back(u-n);
}
}
}
w1.clear();
}
for(int i=; i<=n; i++)
{
sort(ans[i].begin(),ans[i].end());
int len=ans[i].size();
printf("%d",len);
for(int j=; j<len; j++)
{
printf(" %d",ans[i][j]);
}
printf("\n");
}
return ;
}
King's Quest POJ - 1904 匈牙利算法的思想+tarjan缩点+染色的更多相关文章
- King's Quest - poj 1904(强连通分量+外挂输入输出)
题意:国王有N个儿子,每个儿子都有很多喜欢的姑娘,官员为每个王子都找了一个姑娘让他们结婚,不过国王不满意,他想知道他的每个儿子都可以和那个姑娘结婚(前提他的儿子必须喜欢那个姑娘) 分析:因为最下面一行 ...
- King's Quest POJ - 1904(强连通分量)
建图:王子u喜欢女孩v,则u到v连一条边.对于给出的初始完美匹配,王子u与女孩v匹配,则v到u连一条边.然后求SCC. 显然对于同一个SCC中王子数目和女孩数目是相等的,并且从某个王子出发能够到达所有 ...
- POJ 1236 Network of Schools(Tarjan缩点)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16806 Accepted: 66 ...
- POJ 3041 匈牙利算法模板题
一开始预习是百度的算法 然后学习了一下 然后找到了学长的ppt 又学习了一下.. 发现..居然不一样... 找了模板题试了试..百度的不好用 反正就是wa了..果然还是应当跟着学长混.. 图两边的点分 ...
- Asteroids POJ - 3041 匈牙利算法+最小点覆盖König定理
题意: 给出一个N*N的地图N 地图里面有K个障碍 你每次可以选择一条直线 消除这条直线上的所有障碍 (直线只能和列和行平行) 问最少要消除几次 题解: 如果(x,y)上有一个障碍 则把 ...
- POJ 2446 匈牙利算法
题意: 思路: 二分图匹配... // by SiriusRen #include <cmath> #include <cstdio> #include <cstring ...
- POJ 2239 匈牙利算法
思路:最大匹配 也是很裸的一道题-. // by SiriusRen #include <cstdio> #include <cstring> #include <alg ...
- POJ 2536 匈牙利算法
思路:最大匹配 (很裸) // by SiriusRen #include <cmath> #include <cstdio> #include <cstring> ...
- poj 1236 Network of Schools(tarjan+缩点)
Network of Schools Description A number of schools are connected to a computer network. Agreements h ...
随机推荐
- Cobbler环境搭建
Cobbler服务器系统: CentOS 6.6 64位Cobbler版本: cobbler-2.6.11IP地址:192.168.166.136 1.安装epel库 rpm -ivh http:// ...
- Spring学习-1 框架总览
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. spring ...
- Vue.js checkbox 练习
<div id="app"> <input type=" />足球 <input type=" />篮球 <input ...
- HDU4681_String
这个题目是这样的. 给你三个字符串A,B,C,(C一定是A和B的一个公共子序列). 现在要求你构造出一个串D,使得D同时为A和B的子序列,且C是D的一个连续子串.求D的最大可能长度. 很简单的一个DP ...
- HDU 6035 Colorful Tree(dfs)
题意:一棵有n个点的树,树上每个点都有颜色c[i],定义每条路径的值为这条路径上经过的不同颜色数量和.求所有路径的值的和. 可以把问题转化为对每种颜色有多少条不同的路径至少经过这种颜色的点,然后加和. ...
- java中的error该不该捕获
写java程序时,通常会被提示捕获异常,而又有一些异常是不需要强制捕获的,这是一个被说烂了的话题.像我一样从其他语言转过来的人确实有点迷惑,那我以我的理解重新解释一遍吧. 异常的基类是Exceptio ...
- QT uic rcc moc 命令行使用
QT uic rcc moc 命令行使用 PS C:\Users\lsgx> uic.exe --help Usage: C:\Qt\Qt5.5.1\5.5\msvc2012\bin\uic.e ...
- BZOJ2716:[Violet 3]天使玩偶——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2716 样例输入 2 31 12 32 1 21 3 32 4 2 样例输出 1 2 ———————— ...
- SQLite中的自增关键字:AUTO_INCREMENT、INTEGER PRIMARY KEY与AUTOINCREMENT
1.SQLite不支持关键字AUTO_INCREMENT 1)AUTO_INCREMENT不生效的问题 SQL语句: CREATE TABLE todo ( id INTEGER AUTO_I ...
- bzoj2956: 模积和(数论)
先算出无限制的情况,再减去i==j的情况. 无限制的情况很好算,有限制的情况需要将式子拆开. 注意最后的地方要用平方和公式,模数+1是6的倍数,于是逆元就是(模数+1)/6 #include<i ...