Directed Roads

题目链接:http://codeforces.com/contest/711/problem/D

dfs

刚开始的时候想歪了,以为同一个连通区域会有多个环,实际上每个点的出度为1,也就是说每个连通区域最多就只有一个环。

那么每一个连通区域的方法数就 = (2^环内边数-2)*(2^环外边数) [因为环内有两种情况形成圈,不可取],

总方法数 = 不同连通区域的方法数的乘积;

于是我把整个有向图先存储成无向图,用dfs判断该连通区域有没有环,再cls掉环外的边,之后再继续dfs...

代码如下:

 #include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#define N 200005
#define M (int)(1e9+7)
#define special 9
using namespace std;
typedef long long LL;
struct nod{
LL edge;
LL to;
nod(LL a,LL b){
edge=a;
to=b;
}
};
vector<nod>node[N];
LL n;
LL vis[N];
LL dfs(LL index,LL num){
for(LL i=;i<node[index].size();++i){
LL e=node[index][i].edge,to=node[index][i].to;
if(vis[e]==-){
vis[index]=to;
LL temp=dfs(e,num+);
if(temp)return temp;
vis[index]=-;
}else if(vis[e]==to){
vis[index]=to;
vis[e]=special;
return num;
}
}
return ;
}
LL cls(LL index,LL num){
for(LL i=;i<node[index].size();++i){
vis[index]=-;
LL e=node[index][i].edge;
if(vis[e]==special)return num;
if(vis[e]!=-)
return cls(e,num+);
}
return ;
}
LL pow(LL a,LL b){
LL base=a,temp=;
while(b){
if(b&)temp=(temp*base)%M;
base=(base*base)%M;
b>>=;
}
return temp;
}
LL mod(LL a,LL b){
LL base=a,temp=;
while(b){
if(b&)temp=(temp+base)%M;
base=(base+base)%M;
b>>=;
}
return temp;
}
int main(void){
memset(vis,-,sizeof(vis));
LL res=;
scanf("%I64d",&n);
for(LL i=;i<=n;++i){
LL vertice;
//cin>>vertice;
scanf("%I64d",&vertice);
node[i].push_back(nod(vertice,));
node[vertice].push_back(nod(i,));
}
for(LL i=;i<=n;++i){
if(vis[i]==-){
LL cyc_temp=dfs(i,);
if(vis[i]!=special&&vis[i]!=-){
LL un_temp=cls(i,);
cyc_temp-=un_temp;
}
if(res==&&cyc_temp)res=pow(,cyc_temp)-;
else if(cyc_temp)res=mod(res,(pow(,cyc_temp)-));
}
}
LL un_sum=;
for(LL i=;i<=n;++i)
if(vis[i]==-)un_sum++;
if(res)res=mod(res,pow(,un_sum));
else res=pow(,un_sum);
//cout<<res<<endl;
printf("%I64d\n",res);
}

然而这样会T(想象一种坏的情况:只有一个连通区域,且环在末尾,这样差不多是O(n^2)的复杂度)

仔细想过后,其实不需要将有向图转化为无向图,因为每个点的出度为1,如果有环,那么有向图也必然成环,改进后复杂度就成了O(n)

代码如下:

 #include<cstdio>
#include<cstring>
#include<iostream>
#define N 200005
#define M (int)(1e9+7)
using namespace std;
typedef long long LL;
LL n,sum=;
LL a[N];
LL vis[N];
LL pow(LL a,LL b){
LL base=a,temp=;
while(b){
if(b&)temp=(temp*base)%M;
base=(base*base)%M;
b>>=;
}
return temp;
}
int main(void){
cin>>n;
LL res=n;
for(LL i=;i<=n;++i)cin>>a[i];
for(LL i=;i<=n;++i){
if(!vis[i]){
LL index=i;
while(){
vis[index]=i;
index=a[index];
if(vis[index])break;
}
if(vis[index]!=i)continue;
LL node=,temp=index;
while(){
node++;
temp=a[temp];
if(temp==index)break;
}
res-=node;
sum=(sum*(pow(,node)-))%M;
}
}
sum=(sum*pow(,res))%M;
cout<<sum<<endl;
}

Directed Roads的更多相关文章

  1. Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量

    D. Directed Roads   ZS the Coder and Chris the Baboon has explored Udayland for quite some time. The ...

  2. Codeforces #369 div2 D.Directed Roads

    D. Directed Roads time limit per test2 seconds memory limit per test256 megabytes inputstandard inpu ...

  3. CodeForces #369 div2 D Directed Roads DFS

    题目链接:D Directed Roads 题意:给出n个点和n条边,n条边一定都是从1~n点出发的有向边.这个图被认为是有环的,现在问你有多少个边的set,满足对这个set里的所有边恰好反转一次(方 ...

  4. codeforces 711D D. Directed Roads(dfs)

    题目链接: D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  5. Code Forces 711D Directed Roads

    D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  6. Codeforces Round #369 (Div. 2) D. Directed Roads (DFS)

    D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  7. Codeforces 711D Directed Roads - 组合数学

    ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it co ...

  8. Codeforces Round #369 (Div. 2) D. Directed Roads 数学

    D. Directed Roads 题目连接: http://www.codeforces.com/contest/711/problem/D Description ZS the Coder and ...

  9. Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂

    题目链接:http://codeforces.com/problemset/problem/711/D D. Directed Roads time limit per test 2 seconds ...

随机推荐

  1. 访问mysql出现“Access denied for user root@localhost”(using password:NO)解决方案

    首先声明,出现这个提示的原因有很多,以下只针对我遇到的一种情况 使用解压缩版安装mysql的时候,data文件夹是自己新建的,my-default.ini也是自己配置的,这时直接启动mysql服务的时 ...

  2. 获取Storyboard中的视图控制器

    storyboard对于框架的构建是一个非常方便的工具,我们经常需要在storyboard中获取我们指定的视图控制器,那么要怎么获取呢? 方法如下: 第一步:选中视图,为视图自定义一个Storyboa ...

  3. android中edittext被键盘挡住问题

    最近开始新项目,做注册页时候由于ui布局问题,edittext被键盘挡住了. 在stackoverflow上找了一遍,有提到在对应activity中设置windowSoftInputMode, 例如: ...

  4. java集合图示

  5. iOS GCD基础篇 - 同步、异步,并发、并行的理解

    1.关于GCD - GCD全称是Grand Central Dispatch  - GCD是苹果公司为多核的并行运算提出的解决方案  - GCD会自动利用更多的CPU内核(比如双核.四核)  - GC ...

  6. PHP不使用递归的无限级分类

    不用递归实现无限级分类,简单测试了下性能比递归稍好一点点点,但写得太复杂了,还是递归简单方便点 代码: <?php $list = array( array('id'=>1, 'pid'= ...

  7. CodeForces 709A Juicer

    简单题. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #inclu ...

  8. JUnit——(二)注解

    1. 两种错误:Error和Failure Error是代码错误 @Test publicvoid testAdd() { int z=new T().add(5,3); assertEquals(8 ...

  9. trove instance service 总结

    def create(self, req, body, tenant_id): # TODO(hub-cap): turn this into middleware LOG.info(_LI(&quo ...

  10. java实现的简单词法分析器

    一个简单的词法分析器 词法分析(Lexical Analysis) 是编译的第一阶段.词法分析器的主要任务是读入源程序的输入字符.将他们组成词素,生成并输出一个词法单元序列,每个词法单元对应一个词素. ...