P3436 [POI2006]PRO-Professor Szu

题目描述

n个别墅以及一个主建筑楼,从每个别墅都有很多种不同方式走到主建筑楼,其中不同的定义是(每条边可以走多次,如果走边的顺序有一条不同即称两方式不同)。

询问最多的不同方式是多少,以及有多少个别墅有这么多方式,按照顺序输出别墅编号。

如果最多不同方式超过了36500那么都视作zawsze

输入输出样例

输入样例#1:

3 5
1 2
1 3
2 3
3 4
3 4
输出样例#1:

4
1
1

这题反向建个图,缩个点,跑个topo就没了?显然没有这么容易,这里说一下题目的坑点。首先这个题目是要求从n+1号结点出发,那么如果n+1号点不能到达所有的结点会怎么样呢?

看上面这张图,假设这是我们的反向图,按理说我们应该从6号点开始topo,但是5号点自始至终都不会入队,所以说4号点的入度就不可能减到0,这样的话4号点就无法进行topo,那么这样的答案也肯定是错的。要解决这个问题也很简单,就是在缩点时只缩从n+1号点能到达的结点,然后再建新图,而且建的新图中不能含有从n+1号点不能到达的结点。

 tarjan(n+);//这里只从n+1号点开始缩点
for(int i=;i<=n+;i++)
{
if(!dfn[i]) continue;//如果某一个点是n+1号点无法到达的,那么就不能把这个点加到图中
for(int j=last[i];j;j=g[j].next)
{
int v=g[j].to;
if(co[i]!=co[v])
{
add1(co[i],co[v]);
de[co[v]]++;
}
}
}

建图

但是这样还是A不了,这又是为啥呢?原来是自环惹的祸。

看上边的图,我们已经解决了五号点这个从起点无法到达的点的问题了,但是如果四号点给你来一个自环,那不好意思,你又挂了,要是按正常的缩点的话,四号点应该自己单独成为一个强联通分量,按理应该不需要管他,直接dp就好了,但是如果有自环,那么只要经过4号点,方案数就一定会变为正无穷,所以说,自环也是一定要考虑在内的,但是该怎么做呢,这个就更简单了,只需在读入的时候加个特判就好了,最后统计是把自环也当成环处理即可。

 for(int i=;i<=m;i++)
{
aa=read();bb=read();
if(aa==bb)
b[aa]=;//如果有自环,就标记一下;
add(bb,aa);
}

判断自环

然而这样还是A不了,这究竟是为什么呢?后来经我计算发现36500*1000000=36500000000

然后就GG了,果断#define int long long,然后就A了……

真的是巨坑无比的一道题目。

 #include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<stack>
#include<queue>
#define int long long
#define maxn 2000005
using namespace std; struct edge
{
int next,to;
}g[maxn<<],g1[maxn<<];
int n,m,num,tot,col,num1,aa,bb,cnt,tott,pd,de[maxn],t[maxn];
long long ans;
long long f[maxn];
int last[maxn],dfn[maxn],low[maxn],co[maxn],last1[maxn],a[maxn],b[maxn],c[maxn];
stack<int>s;
stack<int>ss; inline int read()
{
char c=getchar();
int x=,res=;
while(c<''||c>'')
{
if(c=='-')
x=-;
c=getchar();
}
while(c>=''&&c<='')
{
res=res*+(c-'');
c=getchar();
}
return x*res;
} void add(int from,int to)
{
g[++num].next=last[from];
g[num].to=to;
last[from]=num;
} void add1(int from,int to)
{
g1[++num1].next=last1[from];
g1[num1].to=to;
last1[from]=num1;
} void tarjan(int u)
{
dfn[u]=low[u]=++tot;
s.push(u);
for(int i=last[u];i;i=g[i].next)
{
int v=g[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!co[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
col++;cnt=;
for(;;)
{
int x=s.top();s.pop();
co[x]=col;
cnt++;
if(x==u) break;
}
a[col]=cnt;
}
} void topo()
{
ss.push(co[n+]);
if(c[co[n+]]==)
{
f[co[n+]]=;
}
else
{
f[co[n+]]=;
}
while(ss.size())
{
int u=ss.top();ss.pop();
for(int i=last1[u];i;i=g1[i].next)
{
int v=g1[i].to;
if(c[v]==)
{
f[v]=;
}
else
{
f[v]+=f[u];
}
de[v]--;
if(de[v]==)
ss.push(v);
}
}
} signed main()
{
n=read();m=read();
for(int i=;i<=m;i++)
{
aa=read();bb=read();
if(aa==bb)
b[aa]=;//如果有自环,就标记一下;
add(bb,aa);
}
tarjan(n+);//这里只从n+1号点开始缩点
for(int i=;i<=n+;i++)
{
if(!dfn[i]) continue;//如果某一个点是n+1号点无法到达的,那么就不能把这个点加到图中
for(int j=last[i];j;j=g[j].next)
{
int v=g[j].to;
if(co[i]!=co[v])
{
add1(co[i],co[v]);
de[co[v]]++;
}
}
}
for(int i=;i<=n+;i++)
{
if(b[i]==)
{
c[co[i]]=;
}
if(a[co[i]]>)
{
c[co[i]]=;
}
}
topo();
for(int i=;i<=n;i++)
{
if(f[co[i]]>)
{
pd=;
}
ans=max(ans,f[co[i]]);
}
if(pd==)
{
printf("zawsze\n");
for(int i=;i<=n;i++)
{
if(f[co[i]]>)
{
t[++tott]=i;
}
}
printf("%d\n",tott);
for(int i=;i<=tott;i++)
{
printf("%d ",t[i]);
}
return ;
}
else
{
printf("%lld\n",ans);
for(int i=;i<=n;i++)
{
if(f[co[i]]==ans)
t[++tott]=i;
}
printf("%d\n",tott);
for(int i=;i<=tott;i++)
{
printf("%d ",t[i]);
}
return ;
}
}

P3436 [POI2006]PRO-Professor Szu的更多相关文章

  1. Tarjan&2-SAT 总结

    \(Tarjan\)&\(2-SAT\) 标签: 知识点总结 安利XZYXZY ps:里面的部分东西来自\(Anson\)和\(yler\)和\(XZY\) 阅读体验:https://zybu ...

  2. Java clone方法(下)

    1.终于调用的是一个JNI方法,即java本地方法,加高速度 2.使用clone方法,分为浅复制.深复制,这里直接使用网上抄来的案例来说明吧: 说明: 1)为什么我们在派生类中覆盖Object的clo ...

  3. [POI2006] PRO-Professor Szu

    Description \(n\) 个别墅以及一个主建筑楼,从每个别墅都有很多种不同方式走到主建筑楼,其中不同的定义是(每条边可以走多次,如果走边的顺序有一条不同即称两方式不同). 询问最多的不同方式 ...

  4. 1512: [POI2006]Pro-Professor Szu

    首先把边反向, 问题转化成求从主建筑楼走向各个点的方案数. 然后缩点,块中的方案数可以直接算. 设f[i]表示走到第i个点的方案数.显然f[i]=∑f[j](存在newedge(j,i))初始时,f[ ...

  5. Enterprise Solution 3.1 企业应用开发框架 .NET ERP/CRM/MIS 开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    行业:基于数据库的制造行业管理软件,包含ERP.MRP.CRM.MIS.MES等企业管理软件 数据库平台:SQL Server 2005或以上 系统架构:C/S 开发技术 序号 领域 技术 1 数据库 ...

  6. vs生成pro

    1.修改.vcxproj文件   <PropertyGroup Label="Globals">    <ProjectGuid>{AAAA4039-13B ...

  7. 高级渲染技巧和代码示例 GPU Pro 7

    下载代码示例 移动设备正呈现着像素越来越高,屏幕尺寸越来越小的发展趋势. 由于像素着色的能耗非常大,因此 DPI 的增加以及移动设备固有的功耗受限环境为降低像素着色成本带来了巨大的压力. MSAA 有 ...

  8. 解析大型.NET ERP系统数据访问 对象关系映射框架LLBL Gen Pro

    LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化. ...

  9. LLBL Gen Pro 5.0 企业应用开发入门

    Solutions Design 公司于2016年5月发布了LLBL Gen Pro 5.0,这个新版本的发布出乎于我的意料.我的猜想是从4.2升级到4.5,再升级5.x版本,主版本号的变更会给原有客 ...

随机推荐

  1. C语言博客作业02--循环结构

    1.本章学习总结 1.1 思维导图 1.2 本章学习体会及代码量学习体会 1.2.1 学习体会 经过本周学习,对c循环结构有了深入,无论是单层循环结构还是嵌套循环结构的问题,我都学会有一定的解决能力, ...

  2. 使用jquery移除前面通过onclick绑定的元素的事件,然后重新绑定别的函数来执行onclick事件。

    http://caibaojian.com/css3/experience/bugs.htm 使用jquery移除前面通过onclick绑定的元素的事件,然后重新绑定别的函数来执行onclick事件. ...

  3. Git——开启区分大小写

    前言 默认情况下git是忽略区分大小写的,多人合作的情况下不规范很容易造成问题,所以开启区分大小写. 步骤 开启 全局开启 git config --global core.ignorecase fa ...

  4. UOJ 7 NOI2014 购票

    题意:给一棵树计算一下各个点在距离限制下以一定的费用公式通过不停地到祖先最后到达一号点的最小花费. 第一种做法:线段树维护带修凸壳.显然的,这个公式计算是p*x+q 所以肯定和斜率有关系.然后这题的d ...

  5. 关于Aop切面中的@Before @Around等操作顺序的说明

    [转]http://www.cnblogs.com/softidea/p/6123307.html 话不多说,直接上代码: package com.cdms.aop.aspectImpl; impor ...

  6. JS学习笔记Day17

    一. 创建对象的方法 (一)在了解原型链之前,首先先了解一下创建对象的几种方式,介绍以下三种. 代码: <script type="text/javascript"> ...

  7. hbase-default.xml(Hbase 默认参数翻译)

    hbase.tmp.dir \({java.io.tmpdir}/hbase-\){user.name} 本地文件系统上的临时目录.将'/tmp'改为其他可以持久保存文件的位置,通常能够解决java. ...

  8. TCP和UDP的优缺点及区别

    1.TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TCP的优点: 可靠,稳定 TCP的可靠体 ...

  9. 【Unity游戏开发】用C#和Lua实现Unity中的事件分发机制EventDispatcher

    一.简介 最近马三换了一家大公司工作,公司制度规范了一些,因此平时的业余时间多了不少.但是人却懒了下来,最近这一个月都没怎么研究新技术,博客写得也是拖拖拉拉,周六周天就躺尸在家看帖子.看小说,要么就是 ...

  10. JVM垃圾回收机制概述

    JVM垃圾回收机制概述 1.定义 是指JVM用于释放那些不再使用的对象所占用的内存. 2.方式 2.1引用计数(早期) 当引用程序创建引用以及引用超出范围时,JVM必须适当增减引用数.当某个对象的引用 ...