【题意】

见:http://blog.csdn.net/ascii991/article/details/7466278

【思路】

缩点+tarjan,思路也可以到上面的博客去看。(吐槽:这道题其实我没有AC。我过了当年IOI的数据,而把别人AC掉的程序带进去,明显过不了IOI的数据!求POJ修正一下!)我在这里引用一下:

找强连通分量,缩点。记f[i]为缩完点后的新图中各点入度,g[i]为出度,ans1为f[i]==0的点的数目,ans2为g[i]==0的点的数目则第一问为ans1,第二问则为max{ans1,ans2}。

至于第二问的解释,我的想法是对于得到的DAG图,考虑其中的出度为0的点和入度为0的点组成的点集V,将这些点相连,最多这需要max{ans1,ans2}条边,就能使整个图成为强连通分量。

但是请注意,大家可能都没发现,这个结论的前提是DAG图是连通的情况下才成立。如果DAG图有多个连通分量,则还要考虑将多个连通分量合并的所需代价。幸运的是,这道题保证了只有一个连通分量。(题目第一句话所说)

【错误点】

1.tarjan要进行多次,详见程序注释

2.循环从0开始还是从1开始要看清楚!

3.但只有一个连通分量的时候,不需要再增加边!

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
using namespace std;
const int MAXN=+;
int n;//学校的总数
int u[MAXN],v[MAXN];//记录每一条边的起始点和终点
int sp[MAXN];//记录缩点之后每个点对应的编号
int tot=;//有向图中边的总数
int vis[MAXN];
int instack[MAXN];
int dfn[MAXN],low[MAXN];
int indegree[MAXN],outdegree[MAXN];//记录缩点后的每一个点的入度与出度
vector<int> E[MAXN];
stack<int> S;
int T=;
int cnt=;//为缩点后的每一个点编号 void tarjan(int u)
{
dfn[u]=low[u]=++T;
vis[u]=;
S.push(u);
instack[u]=; for (int i=;i<E[u].size();i++)
{
int son=E[u][i];
if (!vis[son])
{
tarjan(son);
low[u]=min(low[son],low[u]);
}
else
if (vis[son] && instack[son])
low[u]=min(dfn[son],low[u]);
} if (dfn[u]==low[u])
{
cnt++;
int x;
do
{
x=S.top();
S.pop();
sp[x]=cnt;
instack[x]=;
}while (x!=u);
}
} void init()
{
memset(vis,,sizeof(vis));
memset(instack,,sizeof(instack));
scanf("%d",&n);
for (int i=;i<=n;i++)
{
int to;
while (scanf("%d",&to) && to)
{
tot++;
u[tot]=i;v[tot]=to;
E[i].push_back(to);
}
}
} void find()
{
memset(indegree,,sizeof(indegree));
memset(outdegree,,sizeof(outdegree));
if (cnt>)
{
for (int i=;i<=tot;i++)
/*错误点:写成了i=0;i<tot,导致有时候没有进入循环!*/
{
if (sp[u[i]]!=sp[v[i]])
{
outdegree[sp[u[i]]]++;
indegree[sp[v[i]]]++;
}//找出缩点后各点的出度和入度
} int noin=,noout=;
for (int i=;i<=cnt;i++)
{
if (indegree[i]==) noin++;
if (outdegree[i]==) noout++;
}
cout<<noin<<endl;
cout<<max(noin,noout)<<endl;
}
else if (cnt==) printf("1\n\0\n");
} int main()
{
init();
for (int i=;i<=n;i++) if (vis[i]==) tarjan(i);
/*错误点:一开始直接tarjan(1)了,导致有一些学校没有被访问到!每次随机从没有访问的某个结点开始!*/
find();
return ;
}

【tarjan+缩点】POJ1236[IOI1996]-Network of Schools的更多相关文章

  1. POJ1236:Network of Schools (思维+Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24880   Accepted: 99 ...

  2. poj1236/luogu2746 Network of Schools (tarjan)

    tarjan缩点后,第一问答案显然是入度为零的点得个数第二问:考虑到 没有入度或出度为0的点 的图强连通, 所以答案就是max{入度为零的个数,出度为零的个数} (把出度为零的连到入度为零的点,然后剩 ...

  3. 【poj1236】 Network of Schools

    http://poj.org/problem?id=1236 (题目链接) 题意 给定一个有向图,求:1.至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点:2.至少要加多少条边,才能使得从任 ...

  4. POJ1236:Network of Schools——题解

    http://poj.org/problem?id=1236 首先还是缩点,然后入度为0的点的个数就是你要投文件个数. 然后我们对于入度和出度为0的点的个数取最大值即为答案. (简单证明:入度和出度为 ...

  5. poj1236 Network of Schools【强连通分量(tarjan)缩点】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html  ---by 墨染之樱花 [题目链接]http://poj.org/pr ...

  6. POJ 1236 Network of Schools(Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16806   Accepted: 66 ...

  7. Network of Schools --POJ1236 Tarjan

    Network of Schools Time Limit: 1000MS Memory Limit: 10000K Description A number of schools are conne ...

  8. POJ1236 - Network of Schools tarjan

                                                     Network of Schools Time Limit: 1000MS   Memory Limi ...

  9. POJ1236 Network of Schools (强连通)(缩点)

                                                                Network of Schools Time Limit: 1000MS   ...

随机推荐

  1. Python作业模拟登陆(第一周)

    模拟登陆:1. 用户输入帐号密码进行登陆2. 用户信息保存在文件内3. 用户密码输入错误三次后锁定用户 思路: 1. 用户名密码文件为passwd,锁定用户文件为lock 2. 用户输入账号密码采用i ...

  2. C语言分割字符串函数strtok

    在编程过程中,有时需要对字符串进行分割.而有效使用这些字符串分隔函数将会给我们带来很多的便利. 下面我将在MSDN中学到的strtok函数做如下翻译. strtok :在一个字符串查找下一个符号 ch ...

  3. 第一章:read/sysread/print/syswrite区别

    use strict; use warnings; #将读入的内容添加到原字符串后面 my $buffer='START:'; , length($buffer)); #my $byts = read ...

  4. Python标准库笔记(4) — collections模块

    这个模块提供几个非常有用的Python容器类型 1.容器 名称 功能描述 OrderedDict 保持了key插入顺序的dict namedtuple 生成可以使用名字来访问元素内容的tuple子类 ...

  5. printk %pF %pS含义【转】

    作者:啐楼链接:https://www.zhihu.com/question/37769890/answer/73532192来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...

  6. C语言将字符串转换成对应的数字(十进制、十六进制)【转】

    转自:http://wawlian.iteye.com/blog/1315133 问题1:讲一个十进制数字的字符串表示转换成对应的整数.举例:将“”转换成整数1234. C代码 收藏代码 /*将字符串 ...

  7. FAN54015 充電電流 軟硬體設定

    Ex1: Vrsense 選 37.4 mV --- 在第二張圖 Rsense 選 50 mΩ --- 在第三張圖 37.4 / 50 = 748 mA Ex2: Vrsense 選 44.2 mV ...

  8. .build_release/lib/libcaffe.so: undefined reference to `cv::VideoCapture::set(int, double)'

    CXX/LD -o .build_release/tools/convert_imageset.bin.build_release/lib/libcaffe.so: undefined referen ...

  9. 属性名、变量名与 内部关键字 重名 加&

    procedure TForm4.btn3Click(Sender: TObject); var MyQj: TQJson; MyPrinter: TPrinter; begin MyQj := TQ ...

  10. Highcharts创建一个简单的柱状图

    新建一个html文件,将highcharts引入到你的页面后,通过两个步骤我们就可以创建一个简单的图表了. 1.创建div容器 在页面的 body部分创建一个div,并指定div 的 id,高度和宽度 ...