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版本,主版本号的变更会给原有客 ...
随机推荐
- 浅拷贝(Shallow Copy) VS 深拷贝(Deep Copy)
首先,深拷贝和浅拷贝针对的是对象类型(对象,数组,函数) 浅拷贝指的是只是拷贝了对象的引用地址,彼此之间高耦合,一个改变,另一个可能也随之改变: 深拷贝是指只是完整的将变量的值拷贝过来,是一个新的对象 ...
- springboot项目中配置swagger-ui
Git官方地址:https://github.com/SpringForAll/spring-boot-starter-swagger Demo:https://github.com/dyc87112 ...
- Retrofit原理
Retrofit原理解析最简洁的思路 Retrofit 工作原理总结 从架构角度看Retrofit的作用.原理和启示 Retrofit主要是在create方法中采用动态代理模式实现接口方法:这个过程构 ...
- 搭建alpine仓库 提供apk包
搭建alpine私有仓库从官方拉取alpine所有的包 wget -r -np -nH http://nl.alpinelinux.org/alpine/v3.5/main/x86_64/ wget ...
- zookeeper集群的简单搭建
zookeeper简单介绍 zookeeper是一个为分布式应用提供一致性服务的软件,它是开源的Hadoop项目的一个子项目,并根据google发表的一篇论文来实现的.zookeeper为分布式系统提 ...
- nodejs使用vue从搭建项目到发布部署
都说是使用vue 脚手架自然用的是vue-cli npm install vue-cli -g 建立项目 vue init webpack demo //vue初始化 使用webpack 项目名称 这 ...
- .NET常用开发框架汇总
分布式缓存框架:Microsoft Velocity:微软自家分布式缓存服务框架.Memcahed:一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度.Redis:是一个高性能的KV数据 ...
- Jenkins_安装
1.下载war包 wget -c -O ./jenkins.war http://mirrors.jenkins.io/war-stable/latest/jenkins.war 2.启动下载好的wa ...
- hadoop记录-hadoop常用
1.hdfs目录配额 #设置配额目录hdfs dfsadmin -setSpaceQuota 10T /user/hive/warehouser/tmp查看配额目录信息hdfs dfs -count ...
- HDU 2717(* bfs)
题意是在一个数轴上,每次可以一步到达当前位置数值的 2 倍的位置或者数值 +1 或数值 -1 的位置,给定 n 和 k,问从数值为 n 的位置最少多少步可以到达数值为 k 的位置. 用广搜的方法,把已 ...