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. Kafka connect快速构建数据ETL通道

    摘要: 作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 业余时间调研了一下Kafka connect的配置和使用,记录一些自己的理解和心得,欢迎 ...

  2. 上传代码到GitHub时,遇到错误:fatal,The Requested URL return error 403

    解决: from:pushing-to-git-returning-error-code-403-fatal-http-request-failed

  3. 【LeeetCode】4. Median of Two Sorted Arrays

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  4. 本地存储 cookie,session,localstorage( 二)angular-local-storage

    原文:https://github.com/grevory/angular-local-storage#api-documentation Get Started (1)Bower: $ bower ...

  5. 浙大玉泉ubuntu L2TP VPN连接设置

    网络连接设置 1.内网有线 如果是笔记本且只用无线,剩下的就不需要看了.实验室台式机没有无线网卡不得不折腾-- 玉泉有线都是要绑定固定ip的,实验室无需和mac地址绑定,命令如下sudo gedit ...

  6. 文档在线预览开源实现方案三:OpenOffice + PDFRenderer + js

    之前的方案无法很好地解决异构平台及不同浏览器的兼容性问题,如方案一需要客户端浏览器支持flash而移动端浏览器无法支持这点,虽然移动端浏览器支持方案二,但是一些老版本的IE浏览器无法支持,例如IE8就 ...

  7. java http url post json

    import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import ja ...

  8. IMacro 脚本简记

    抓取速卖通纠纷订单详情,生成csv进行统计. var macro1="CODE:";macro1+="VERSION BUILD=8970419 RECORDER=FX& ...

  9. QWebView 播放网络视频

    最近想看某站的VIP视频,但是网络上的软件用着都不怎么习惯,还有些要收费(收费还不如买VIP了..),所以自己研究做个网络播放器,使用的是QWebView. 1.设置WebView ui->we ...

  10. Unity3D脚本使用:物体调用物体

    如下图4种方式: 方式5 通过Tag定位物体 1.先对物体定义标签Tag,可选已有或自定义 2.通过Tag名称找到对象 注意:如果标签对应多个对象,需使用获取对象集合再进行处理