Directed Roads
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的更多相关文章
- 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 ...
- Codeforces #369 div2 D.Directed Roads
D. Directed Roads time limit per test2 seconds memory limit per test256 megabytes inputstandard inpu ...
- CodeForces #369 div2 D Directed Roads DFS
题目链接:D Directed Roads 题意:给出n个点和n条边,n条边一定都是从1~n点出发的有向边.这个图被认为是有环的,现在问你有多少个边的set,满足对这个set里的所有边恰好反转一次(方 ...
- codeforces 711D D. Directed Roads(dfs)
题目链接: D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- Code Forces 711D Directed Roads
D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 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 ...
- Codeforces 711D Directed Roads - 组合数学
ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it co ...
- Codeforces Round #369 (Div. 2) D. Directed Roads 数学
D. Directed Roads 题目连接: http://www.codeforces.com/contest/711/problem/D Description ZS the Coder and ...
- 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 ...
随机推荐
- zabbix 布署实践【7 H3C网络设备监控模版制作思路】
我们知道,zabbix安装后自带Template OS Linux 模版已满足了绝大部分Linux服务器的基础环境监控,只是我们在其模版上稍微修改,可配合将SWAP监控取消,另存为一个叫OS Linu ...
- java基础练习 11
import java.util.Scanner; public class Eleventh { /*给一个不多于5位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. (5 分数)*/ p ...
- 如何安装并使用bower包依赖工具
什么是bower Bower是一个客户端技术的软件包管理器,它可用于搜索.安装和卸载如JavaScript.HTML.CSS之类的网络资源.其他一些建立在Bower基础之上的开发工具,如YeoMan和 ...
- 【CSS学习笔记】CSS选择器
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- Word 文字转表格
今天工作的时候遇到一个问题,需要整理出一个工程下依赖的jar的名称和大小,并且按照大小排序,我在使用一个java程序打印出名称和大小之后,需要将这些文字整理到word文档表格中,刚开始是想一个个的拷进 ...
- 关于C#继承运用的总结
整体代码部分: 解决方案: 父类Person类: using System; using System.Collections.Generic; using System.Linq; using Sy ...
- C#笔记(一)常量
常量必须在声明时初始化 常量的值必须能在编译时用于计算.因此,不能用从一个变量中提取的值来初始化常量. 常量总是静态的.但注意,不必(实际上,是不允许)在常量声明中包含修饰符static .
- Egret 显示容器
1,显示容器:所有的容器都继承自DisplayObjectContainer , DisplayObjectContainer 又继承自DisplayObject: 2,想定义一个容器只要创建一个类, ...
- python json数组对象排序
arr = [{"name": "name_1", "level": 1}, {"name": "name_2 ...
- <hdu - 1272> 小希的迷宫 并查集问题 (注意特殊情况)
本题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272 Problem Description: 上次Gardon的迷宫城堡小希玩了很久(见Probl ...