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版本,主版本号的变更会给原有客 ...
随机推荐
- apache+php项目部署
先安装apache和php然后进行如下操作(以63服务器的安装路径为例) 1.查看php项目运行的报错信息 路径: cd /var/log/httpd/error_log 如果错误如下: 可以尝试 ...
- icpc 南昌邀请赛网络赛 Max answer
就是求区间和与区间最小值的积的最大值 但是a[i]可能是负的 这就很坑 赛后看了好多dalao的博客 终于a了 这个问题我感觉可以分为两个步骤 第一步是对于每个元素 以它为最小值的最大区间是什么 第二 ...
- Linux跑脚本用sh和./有什么区别?(转)
sh是一个shell.运行sh a.sh,表示我使用sh来解释这个脚本:如果我直接运行./a.sh,首先你会查找脚本第一行是否指定了解释器,如果没指定,那么就用当前系统默认的shell(大多数linu ...
- postgresql 基本使用及常见问题
基本使用参考 https://www.yiibai.com/postgresql/postgresql-insert.html 关于编码问题: 这是一个很复杂,但弄懂之后还是很迷的问题. postgr ...
- jmetter的http请求设置
1.设置 cookie 2.设置header 3.login 4.post请求 5.get请求
- sql server查看表是否死锁
1,查看那个表死锁 select object_name(resource_associated_entity_id) as tableName, request_session_id as pid ...
- P1438 无聊的数列 (差分+线段树)
题目 P1438 无聊的数列 解析: 先考虑修改,用差分的基本思想,左端点加上首项\(k\),修改区间\((l,r]\)内每个数的差分数组都加上公差\(d\),最后的\(r+1\)再减去\(k+(r- ...
- Matlab 中subsystem mask封装子系统
Icon&port %%外型图表封装 %%.曲线型标注: plot(cos(:*pi),sin(:*pi)) %%.文字型标注: disp('PID\n控制器') %%.曲线加文字型标注: p ...
- jmeter笔记(7)--参数化--用户定义的变量
录制的脚本里面有很多的相同的数据的时候,比如服务器ip,端口号等,当更换服务器的时候,就需要手动的修改脚本里面对应的服务器ip和端口号,比较繁琐,jmeter里面有一个用户自定义变量能很好的解决这个问 ...
- 超越村后端开发(3:安装djangorestframework+序列化+API开发前期准备)
1.安装djangorestframework 1.安装djangorestframework及其依赖包markdown.django-filter. pip install djangorestfr ...