对多校赛的题目,我深感无力。题目看不懂,英语是能懂的,题目具体的要求以及需要怎么做没有头绪。样例怎么来的都不明白。好吧,看题解吧。

  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最小路径覆盖的更多相关文章

  1. HDU 3861 The King’s Problem (强连通缩点+DAG最小路径覆盖)

    <题目链接> 题目大意: 一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.所有点只能属于一块区域:2,如果两点相互可达,则这两点必然要属于同一区域:3,区域内任意两点 ...

  2. 【HDU3861 强连通分量缩点+二分图最小路径覆盖】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...

  3. Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖

    题目来源:Light OJ 1406 Assassin`s Creed 题意:有向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路:最少的的人能够走全然图 明显是最小路径覆盖问题 ...

  4. Light OJ 1406 Assassin`s Creed 减少国家DP+支撑点甚至通缩+最小路径覆盖

    标题来源:problem=1406">Light OJ 1406 Assassin`s Creed 意甲冠军:向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路: ...

  5. hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...

  7. HDU 3861 The King's Problem(强连通分量缩点+最小路径覆盖)

    http://acm.hdu.edu.cn/showproblem.php?pid=3861 题意: 国王要对n个城市进行规划,将这些城市分成若干个城市,强连通的城市必须处于一个州,另外一个州内的任意 ...

  8. 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 ...

  9. hdu3861 强连通分量缩点+二分图最最小路径覆盖

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. ubuntu18.0安装RabbitMQ

    RabbitMQ是一个消息队列,用于实现应用程序的异步和解耦.生产者将生产消息传送到队列,消费中从队列中拿取消息并处理.生产者不用关心是谁来消费,消费者不用关系是谁在生产消息,从而达到解耦的目的.本文 ...

  2. 5G vs AI谁更有前途?

    5G vs AI谁更有前途? 5G通信技术和AI人工智能技术是两个不同层面的技术领域,而它们两者都将在未来20年内对世界的发展有着革命性和里程碑式的影响.未来5G和AI谁更有前途呢? 5G技术的发展和 ...

  3. Android 性能测试初探(五)

    书接上文 Android 性能测试初探之 GPU(四) 前文说了的一些性能测试项大家可能都听说,接下来我们聊聊大家不常关注的测试项- 功耗 . 功耗测试主要从以下几个方面入手进行测试 测试手机安装目标 ...

  4. inherit 关键字使得元素获取其父元素的计算值

    它可以应用于任何CSS属性,包括CSS简写 all. 对于继承属性,inherit 关键字只是增强了属性的默认行为,只有在重载(overload)其它规则的时候被使用.对于非继承属性,inherit ...

  5. LINUX - getopts

    getopts optionString opt; optionString :所有参数组成的-参数串: opt:从optionString 每次取的参数值: 当optionString用[:]开头, ...

  6. dd命令测试IO

    在实际环境中,测试IO写性能 首先需要实时监测磁盘的IO sar -d interval count 同时对磁盘进行IO压力写 time dd if=/dev/zero of=baa.img bs=1 ...

  7. Python之CSV模块

    1. CSV简介 CSV(Comma Separated Values)是逗号分隔符文本格式,常用于Excel和数据库的导入和导出,Python标准库的CSV模块提供了读取和写入CSV格式文件的对象. ...

  8. 51nod1079 中国剩余定理【数论】

    一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K.例如,K % 2 = 1, K % 3 = 2, K % 5 = 3.符合条件的最小的K = 23. Input 第1行:1个数N表 ...

  9. 1.3 eclipse中配置Tomcat

    下载并成功安装Eclipse和Tomcat():   打开Eclipse,单击“window”菜单,选择下方的“Preferences”: 步骤阅读 3 找到Server下方的Runtime Envi ...

  10. UVA 1563 - SETI (高斯消元+逆元)

    UVA 1563 - SETI option=com_onlinejudge&Itemid=8&page=show_problem&category=520&probl ...