P3436 [POI2006]PRO-Professor Szu
P3436 [POI2006]PRO-Professor Szu
题目描述
n个别墅以及一个主建筑楼,从每个别墅都有很多种不同方式走到主建筑楼,其中不同的定义是(每条边可以走多次,如果走边的顺序有一条不同即称两方式不同)。
询问最多的不同方式是多少,以及有多少个别墅有这么多方式,按照顺序输出别墅编号。
如果最多不同方式超过了36500那么都视作zawsze
输入输出样例
3 5
1 2
1 3
2 3
3 4
3 4
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的更多相关文章
- Tarjan&2-SAT 总结
\(Tarjan\)&\(2-SAT\) 标签: 知识点总结 安利XZYXZY ps:里面的部分东西来自\(Anson\)和\(yler\)和\(XZY\) 阅读体验:https://zybu ...
- Java clone方法(下)
1.终于调用的是一个JNI方法,即java本地方法,加高速度 2.使用clone方法,分为浅复制.深复制,这里直接使用网上抄来的案例来说明吧: 说明: 1)为什么我们在派生类中覆盖Object的clo ...
- [POI2006] PRO-Professor Szu
Description \(n\) 个别墅以及一个主建筑楼,从每个别墅都有很多种不同方式走到主建筑楼,其中不同的定义是(每条边可以走多次,如果走边的顺序有一条不同即称两方式不同). 询问最多的不同方式 ...
- 1512: [POI2006]Pro-Professor Szu
首先把边反向, 问题转化成求从主建筑楼走向各个点的方案数. 然后缩点,块中的方案数可以直接算. 设f[i]表示走到第i个点的方案数.显然f[i]=∑f[j](存在newedge(j,i))初始时,f[ ...
- 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 数据库 ...
- vs生成pro
1.修改.vcxproj文件 <PropertyGroup Label="Globals"> <ProjectGuid>{AAAA4039-13B ...
- 高级渲染技巧和代码示例 GPU Pro 7
下载代码示例 移动设备正呈现着像素越来越高,屏幕尺寸越来越小的发展趋势. 由于像素着色的能耗非常大,因此 DPI 的增加以及移动设备固有的功耗受限环境为降低像素着色成本带来了巨大的压力. MSAA 有 ...
- 解析大型.NET ERP系统数据访问 对象关系映射框架LLBL Gen Pro
LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化. ...
- LLBL Gen Pro 5.0 企业应用开发入门
Solutions Design 公司于2016年5月发布了LLBL Gen Pro 5.0,这个新版本的发布出乎于我的意料.我的猜想是从4.2升级到4.5,再升级5.x版本,主版本号的变更会给原有客 ...
随机推荐
- Spring Boot 2.x 编写 RESTful API (五) 单元测试
用Spring Boot编写RESTful API 学习笔记 概念 驱动模块 被测模块 桩模块 替代尚未开发完毕的子模块 替代对环境依赖较大的子模块 (例如数据访问层) 示例 测试 Service @ ...
- C++ 中 double、 long double、long 和 long long
double 属于浮点类型,具体为双精度浮点类型,通常为 IEEE-754 64 位浮点类型. long double 也属于浮点类型,具体为扩展精度浮点类型,其精度不低于double,具体由编译器和 ...
- js 调用打印机方法
<button onclick="localdy({php echo $item['order']['id'];})" class="btn btn-xs orde ...
- python并发编程之协程知识点
由线程遗留下的问题:GIL导致多个线程不能真正的并行,CPython中多个线程不能并行 单线程实现并发:切换+保存状态 第一种方法:使用yield,yield可以保存状态.yield的状态保存与操作系 ...
- Linux环境配置错误记录
1. pip install --special_version pip10. 版本. 使用命令: python -m pip install pip== 其中, -m 参数的意思是将库中的pyt ...
- loj6074 子序列
题目链接 思路 首先考虑暴力\(dp\) 用\(f[i][j]\)表示前\(i\)个字符,以\(j\)这个字符结尾的本质不同的字符串个数. 然后就有如下的转移 \(if(s_i==j)\) \[f_{ ...
- MySQL8.0.19主从环境搭建(CentOS7)
默认情况下,复制是异步的,从站不需要永久连接以接收来自主站的更新.根据配置,您可以复制数据库中的所有数据库,所选数据库甚至选定的表. MySQL中复制的优点包括: 横向扩展解决方案 - 在多个从站之间 ...
- cocos2d中个类之间的关系
1.Director类: (1)单例类Director::getInstance() ,获取导演类对象 (2)设置游戏配置(OpenGL),推动游戏发展 runWithSence.replaceSe ...
- easyui Datagrid 表格高度计算及自适应页面的实现
因为页面上既要计算表格的高度,又要自适应浏览器大小,之前都都采用固定表格高度,这样就会导致不同的分辨率电脑上看起来表格高矮不一, 所以采用了计算网页高度和其他div 的高度之差作为表格的初始高度: H ...
- kubernetes之flannel
kubernetes网络通信 容器间的通信 pod内的容器通信(lo) Pod之间的通信 pod IP <-----> pod IP Pod与Service之间的通信 podIP ...