hdu3861 The King’s Problem 强连通缩点+DAG最小路径覆盖
对多校赛的题目,我深感无力。题目看不懂,英语是能懂的,题目具体的要求以及需要怎么做没有头绪。样例怎么来的都不明白。好吧,看题解吧。
http://www.cnblogs.com/kane0526/archive/2013/07/21/3203992.html
题目大意:
把一幅有向图中的点最少可以划分为几个区域。划分的规则是:1、可以互相到达的点必须在同一区域。2、每个城市都必须被划分。3、对于属于同一区域中的任意两点,要么满足u->v,要么满足v->u。
第三条规则需要着重解释一下。对于测试数据1->2,1->3,因为2与3之间没有边,所以2与3必须被划为2个区域。所以答案是2。
做法:
建图求强连通(Tarjan算法),然后对得到的DAG,重新建图。遍历每条边,不属于同一连通分支的点就连一条边。正向图和反向图都可以。
最后答案就是SCC - ans。SCC 是连通分支数,ans是最大匹配数。因为这里求的最小路径覆盖。
最小路径覆盖 = 顶点数 - 最大匹配数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int N =, M=,INF=0x3f3f3f3f;;
struct node
{
int to, next;
}edge[M];
int head[N], low[N], dfn[N], sta[N], belg[N], num[N];
bool vis[N];
int scc,index,top, tot;
void tarbfs(int u)
{
int i,j,k,v;
low[u]=dfn[u]=++index;
sta[top++]=u;
vis[u]=;
for(i=head[u];i!=-;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
tarbfs(v);
if(low[u]>low[v]) low[u]=low[v];
}
else if(vis[v]&&low[u]>dfn[v]) low[u]=dfn[v];
}
if(dfn[u]==low[u])
{
scc++;
do
{
v=sta[--top];
vis[v]=;
belg[v]=scc;
num[scc]++;
}
while(v!=u) ;
}
}
void Tarjan(int n)
{
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(num,,sizeof(num));
memset(low,,sizeof(low));
index=scc=top=;
for(int i=;i<=n;i++)
if(!dfn[i]) tarbfs(i);
}
void init()
{
tot=;
memset(head,-,sizeof(head));
}
void addedge(int i,int j)
{
edge[tot].to=j; edge[tot].next=head[i];head[i]=tot++;
}
int cx[N],cy[N],dx[N],dy[N];
bool bmask[N];
int nx,dis,ans;
vector<int> bmap[N];
bool searchpath()
{
queue<int> q;
dis=INF;
memset(dx,-,sizeof(dx));
memset(dy,-,sizeof(dy));
for(int i=;i<=nx;i++)
{
if(cx[i]==-){ q.push(i); dx[i]=; }
while(!q.empty())
{
int u=q.front(); q.pop();
if(dx[u]>dis) break;
for(int i=;i<bmap[u].size();i++)
{
int v=bmap[u][i];
if(dy[v]==-)
{
dy[v]= dx[u] + ;
if(cy[v]==-) dis=dy[v];
else
{
dx[cy[v]]= dy[v]+;
q.push(cy[v]);
}
}
}
}
}
return dis!=INF;
}
int findpath(int u)
{
for(int i=;i<bmap[u].size();i++)
{
int v=bmap[u][i];
if(!bmask[v]&&dy[v]==dx[u]+)
{
bmask[v]=;
if(cy[v]!=-&&dy[v]==dis) continue;
if(cy[v]==-||findpath(cy[v]))
{
cy[v]=u; cx[u]=v;
return ;
}
}
}
return ;
}
void maxmatch()
{
ans=;
memset(cx,-,sizeof(cx));
memset(cy,-,sizeof(cy));
while(searchpath())
{
memset(bmask,,sizeof(bmask));
for(int i=;i<=nx;i++)
if(cx[i]==-) ans+=findpath(i);
}
}
int main()
{
//freopen("test.txt","r",stdin);
int cas,i,j,k,n,m;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
init();
while(m--)
{
scanf("%d%d",&i,&j);
addedge(i,j);
}
Tarjan(n);
for(i=;i<=n;i++) bmap[i].clear();
for(i=;i<=n;i++)
{
for(k=head[i];k!=-;k=edge[k].next)
{
j=edge[k].to;
if(belg[i]!=belg[j]) bmap[belg[j]].push_back(belg[i]);
}
}
nx=scc;
maxmatch();
printf("%d\n",scc-ans);
}
return ;
}
hdu3861 The King’s Problem 强连通缩点+DAG最小路径覆盖的更多相关文章
- HDU 3861 The King’s Problem (强连通缩点+DAG最小路径覆盖)
<题目链接> 题目大意: 一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.所有点只能属于一块区域:2,如果两点相互可达,则这两点必然要属于同一区域:3,区域内任意两点 ...
- 【HDU3861 强连通分量缩点+二分图最小路径覆盖】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...
- Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖
题目来源:Light OJ 1406 Assassin`s Creed 题意:有向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路:最少的的人能够走全然图 明显是最小路径覆盖问题 ...
- Light OJ 1406 Assassin`s Creed 减少国家DP+支撑点甚至通缩+最小路径覆盖
标题来源:problem=1406">Light OJ 1406 Assassin`s Creed 意甲冠军:向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路: ...
- hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
The King’s Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...
- HDU 3861 The King's Problem(强连通分量缩点+最小路径覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=3861 题意: 国王要对n个城市进行规划,将这些城市分成若干个城市,强连通的城市必须处于一个州,另外一个州内的任意 ...
- hdu 3861 The King’s Problem trajan缩点+二分图匹配
The King’s Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- hdu3861 强连通分量缩点+二分图最最小路径覆盖
The King’s Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
随机推荐
- 崂山白花蛇草水 权值线段树套KDtree
Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履行诺言的时 ...
- Package和Activity
Package Package 包.只是在我们的app中这个Package是唯一的,就像你身份证号码一样.在我们做app自动化时,我们就需要知道他的Package,我们知道了Package那么也就知道 ...
- Vue push() pop() shift() unshift() splice() sort() reverse() ...
Vue 变异方法 push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度. pop() 方法用于删除并返回数组的最后一个元素. shift() 方法用于把数组的第一个元素从其中删除,并返回 ...
- php中的empty()方法
empty() 判断一个变量是否为“空”,isset() 判断一个变量是否已经设置.empty还会检测变量是否为空.为零.当一个变量值为0,empty() 认为这个变量同等于空,即相当于没有设置.例如 ...
- HTML学习笔记之基本介绍
超文本标记语言 (Hyper Text Markup Language,HTML)不是一种编程语言,而是一种标记语言,用一套标记标签描述网页 HTML 标记标签又被称为 HTML 标签(HTML Ta ...
- [bzoj1708][Usaco2007 Oct]Money奶牛的硬币_动态规划_背包dp
Money奶牛的硬币 bzoj-1708 Usaco-2007 Oct 题目大意:在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币 ...
- spring boot下接口调用失败重试方案
背景: 在项目开发中,有时候会出现接口调用失败,本身调用又是异步的,如果是因为一些网络问题请求超时,总想可以重试几次把任务处理掉. 一些RPC框架,比如dubbo都是有重试机制的,但是并不是每一个项目 ...
- 收到微软寄来的MVP包裹
经过一年多的艰苦努力,最终在7月份获得了微软SharePoint的MVP. 今天收到了微软从美国寄来的包裹. 内部图: 奖牌: 回忆过去一年.白天和客户撕逼,晚上回家写博客,或者翻译英文文章,去论坛回 ...
- 错误总结之播放器(vitamio)音量实体键与触摸手势控制,音量调节冲突
这个但是独家心得:经过几天的网上资料查询未果,在群里遇到一同行. 然后让他帮我看了看,终于攻克了该冲突. 此时,谨以此来感谢那位同僚的热情帮助: 说说这个问题吧: 眼下我在做一款影视方面的项目,在该项 ...
- mysql选择上一条、下一条数据记录,排序上移、下移、置顶
1.功能须要 完毕列表排序上移,下移,置顶功能.效果例如以下图所看到的: 2设置思路 设置一个rank为之间戳,通过选择上移,就是将本记录与上一条记录rank值交换,下移就是将本条记录与下一条记录ra ...