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版本,主版本号的变更会给原有客 ...
随机推荐
- nginx 返回json格式内容
例子: #如果访问的ip是192.168.1.1,就直接返回json格式的内容 location / { default_type application/json; #####格式 if ( $re ...
- Nginx CONTENT阶段 concat模块
L67 concat_delimiter : 根据js 指定 分隔符 比如 “|” 那么每个文件分隔符为 “|” concat_types : 指定要合并文件的类型 concat_unique : s ...
- LVS负载均衡DR模式实现
LVS负载均衡之DR模式配置 DR 模式架构图: 操作步骤 实验环境准备:(centos7平台) 所有服务器上配置 # systemctl stop firewalld //关闭防火墙 # sed - ...
- Hall定理 二分图完美匹配
充分性证明就先咕了,因为楼主太弱了,有一部分没看懂 霍尔定理内容 二分图G中的两部分顶点组成的集合分别为X, Y(假设有\(\lvert X \rvert \leq \lvert Y \rvert\) ...
- Java:IO流-流的操作规律和转换流
首先我们先来了解一些IO流基本知识. 一,基本知识概括 具体的IO流有很多种,针对不同的应用场景应该使用相应的流对象.但怎么确定应该使用哪个IO流对象呢? 一般要有四个明确: 1)明确源和目的 源:I ...
- 第四周博客作业<西北师范大学|李晓婷>
1.助教博客链接:https://home.cnblogs.com/u/lxt-/ 2.作业要求链接:www.cnblogs.com/nwnu-daizh/p/10487329.html 3.本周点评 ...
- codeforces-1133 (div3)
A.先全部化成分钟数,取平均数之后化成正常时刻. #include <map> #include <set> #include <ctime> #include & ...
- loadrunner 添加集合点和添加压力机
loadrunner 添加集合点和添加压力机 一.添加集合点: 1.在脚本中右键insert--rendezvous (集合点一定要添加在事务的外面,否则影响事务准确性) 2.创建controller ...
- DEV 控件使用之:TreeList
使用DEV控件也有一段时间了,一直想写点东西.最近又使用到TreeList控件,这个控件对于刚使用的人来说确实不好掌握.我想把自己知道的写下来,让还不熟悉的慢慢学会使用,对于会使用的大家交流下.如果有 ...
- Ubuntu屏幕分辨率无1920 1080
xrandr 没有1920X1080分辨率,所以手动添加一个1080P分辨率,先输入“cvt 1920 1080”命令,查询一下1080P分辨率的有效扫描频率 然后 sudo xrandr --new ...