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. SQL SERVER BUG--Alwayson日志备份报错

    数据库版本 SQL SERVER 2012 企业版,版本号:11.0.5582.0 问题场景: 数据库配置Alwayson环境,同机房2节点同步自动切换+跨机房异步,在异步机房中选取同一节点做完整备份 ...

  2. (十一)if...else&for循环&while循环

    ----------------------------------if else------------------------------1.最基本的if语句:if name =="Al ...

  3. 记一次Debian下PHP环境的搭建(nginx+mariadb+PHP)!

    顺序是先安装nginx,然后安装mariadb,最后安装PHP.系统用的是debian7 安装nginx sudo apt-get install nginx 我这里用的是稳定的源,没用测试的源,所以 ...

  4. Spring MVC 返回json数据 报406错误 问题解决方案

    将jackson jar包改为jackson-databind-2.5.0.jar  jackson-core-2.5.0.jar  jackson-annotations-2.5.0.jar(这个版 ...

  5. CentOS7 离线安装gcc/pcre-devel/openssl-devel/zlib-devel

    1. 解压CentOS7操作系统安装镜像,进入到CentOS-7.0-1406-x86_64-DVD\Packages目录,这下面存储了很多rpm包. 2. 找到下面列出的rpm包,上传到CentOS ...

  6. netty(5)高级篇-私有协议栈

    来源:<Netty权威指南>  作者:李林峰 一.私有协议介绍 由于现代软件的复杂性,一个大型软件系统往往会被人为地拆分称为多个模块,另外随着移动互联网的兴起,网站的规模越来越大,业务功能 ...

  7. C# 语言规范_版本5.0 (第19章 附录A_文档注释)

    A. 文档注释 C# 提供一种机制,使程序员可以使用含有 XML 文本的特殊注释语法为他们的代码编写文档.在源代码文件中,可以使用特定形式的注释来指导工具从这些注释及其后的源代码元素生成 XML.使用 ...

  8. Android中设定EditText的输入长度

    方法一:可以在layout xml中加上属性android:maxLength 比如: <EditText         android:id="@+id/editTextShow& ...

  9. NGINX----源码阅读---have配置脚本

    /auto/have have配置脚本负责在$NGX_OBJS/ngx_auto_config.h定义宏 # Copyright (C) Igor Sysoev # Copyright (C) Ngi ...

  10. java自带的监控工具VisualVM一

    转自:http://www.cnblogs.com/wade-xu/p/4369094.html 这篇总结的很不错(本人亲自操手学习),留着以后复习备用,很适合入门级的学习者: VisualVM 是一 ...