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 ...
随机推荐
- Spring Cloud 架构 五大神兽的功能
什么是微服务 微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”. 微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调 ...
- 九度-题目1026:又一版 A+B
http://ac.jobdu.com/problem.php?pid=1026 题目描述: 输入两个不超过整型定义的非负10进制整数A和B(<=231-1),输出A+B的m (1 < m ...
- FZU2122_又见LKity
题目是说给你一个替换串和目标串.把一个长串中的所有的替换串替换为目标串而且不递归地替换. 很简单,直接做一次KMP然后直接替换. 注意替换后跳到替换串的尾部. 注意大小写的问题. #include & ...
- Problem D - Non-boring sequences——Contest1004 - National Day Training Contest -- Day3
今天比赛的时候做的一个坑题.深坑啊. 题目意思是给你一个有n个数的数字序列.要你判断对于这个序列是都满足任意一个子序列都至少含有一个只出现一次的数字. 看完题目后没什么思路,一直以为要用线段树,每次删 ...
- resp.getWriter().print的注意点
- 飞舞的蝴蝶(GraphicsView框架)
飞舞的蝴蝶(GraphicsView框架) 一.简介 GraphicsView框架结构主要包含三个主要的类QGraphicsScene(容器).QGraphicsView(视图).QGraphicsI ...
- Codeforces707Div2
A Small, but very brave, mouse Brain was not accepted to summer school of young villains. He was ups ...
- Alpha 冲刺 —— 十分之一
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作,对多个目标检测及文字识别模型进行评估.实验,选取较 ...
- Hadoop1.2.1异常No route to host
Hadoop1.2.1异常Bad connect ack with firstBadLink (No route to host ) 0.说明 Hadoop集群之前运行正常,增加了新节点之后,需要执行 ...
- python基础----迭代器、生成器、协程函数及应用(面向过程实例)
一.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代 ...