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

题目大意:Udayland有一些小镇,小镇和小镇之间连接着路,在某些区域内,如果从小镇Ai开始,找到一个环,环中每个小镇只经过一次,最终回到了Ai,那么认为这个环是混乱的,现在需要治理这种混乱。可以做的操作是改变环上某个小镇Ak到小镇Aj路的方向,使得无法从Ai开始绕这个环再次回到Ai,那么可以认为混乱被治理,问需有多少种改变路径方向的方案可以使得整个Udayland不混乱?求出方案数。

题解思路:涉及到环,首先要求出强联通分量个数,建图套一下tarjan的模板。对于每个强连通分量,在此题意的限制条件下,其边的数量为每个强连通分量的点的数量,那么从tarjan中可以轻易得到边的数量,每条边的方向可以是正反两种,由于可以改变边的方向,那么整个强连通分量的边可以变为2的n次方种(n是某个强连通分量中点的个数),若是形成环路(即强连通分量),只能是正序A1 ->A2 ->A3 ....Ak-1 -> Ak->A1或者是逆序A1->Ak -> Ak-1->....A2->A1两种情况,这两种被认为是混乱的,所以可以改变成不混乱的情况有pow(2,n) - 2种,那么最终的答案就是所有强连通分量不混乱的情况的方案数相乘了,求解过程中根据题意求余即可。

AC代码:

#include<iostream>
#include<vector>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;
struct node{
vector<int> vex;
};
node g[200008];
int dfn[200008];
int low[200008];
int visit[200008];
stack<int> stk;
int ans = 0;
int tot;
int cnt;
vector<int> sum;
void tarjan(int x){
dfn[x] = low[x] = ++tot;
visit[x] = 1;
stk.push(x);
for(int i = 0;i<g[x].vex.size();i++){
if(!dfn[g[x].vex[i]]){
tarjan(g[x].vex[i]);
low[x] = min(low[x],low[g[x].vex[i]]);
}
else if(visit[g[x].vex[i]]){
low[x] = min(low[x],dfn[g[x].vex[i]]);
}
}
if(low[x] == dfn[x]){
int temp = 0;//记录每个连通分量的节点个数
ans++;
while(x!=stk.top()){
temp++;
visit[stk.top()] = 0;
stk.pop();
}
temp++;
visit[stk.top()] = 0;
stk.pop();
if(temp>1)
cnt+=temp;
sum.push_back(temp); //记录每个连通分量的节点个数
}
}
int main(){
int N;
cin>>N;
for(int i = 1;i<=N;i++){
int Ai;
cin>>Ai;
g[i].vex.push_back(Ai);
}
for(int i = 1;i<=N;i++){//套tarjan模板求强连通分量
if(!dfn[i])
tarjan(i);
}
long long int fac[200008];
int mod = 1000000007;
fac[0] = 1;
for(int i = 1;i<=N;i++){
fac[i] = (fac[i-1]*2)%mod;//打表 2的n次方和mod求余
}
long long int res = fac[N-cnt]%mod;
for(int i = 0;i<ans;i++){
if(sum[i]>1)
res = res * (fac[sum[i]]-2+mod)%mod;
}
cout<<res%mod;
return 0;
}

codeforces 711 D.Directed Roads(tarjan 强连通分量 )的更多相关文章

  1. Codeforces 711 D. Directed Roads (DFS判环)

    题目链接:http://codeforces.com/problemset/problem/711/D 给你一个n个节点n条边的有向图,可以把一条边反向,现在问有多少种方式可以使这个图没有环. 每个连 ...

  2. Tarjan 强连通分量 及 双联通分量(求割点,割边)

    Tarjan 强连通分量 及 双联通分量(求割点,割边) 众所周知,Tarjan的三大算法分别为 (1)         有向图的强联通分量 (2)         无向图的双联通分量(求割点,桥) ...

  3. tarjan 强连通分量

    一.强连通分量定义 有向图强连通分量在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly c ...

  4. tarjan强连通分量模板(pascal)

    友好城市 [问题描述]小 w 生活在美丽的 Z 国. Z 国是一个有 n 个城市的大国, 城市之间有 m 条单向公路(连接城市 i. j 的公路只能从 i 连到 j). 城市 i. j 是友好城市当且 ...

  5. 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)

    题目大意:CodeVs2822的简单版本 传送门 $Tarjan$强连通分量+缩点,若连通块的个数等于一则输出n:若缩点后图中出度为0的点个数为1,输出对应连通块内的点数:否则输出0: 代码中注释部分 ...

  6. Codeforces Round #244 (Div. 2) C. Checkposts (tarjan 强连通分量)

    题目:http://codeforces.com/problemset/problem/427/C 题意:给你n座城市,m条有向道路,然后有一个机制,你在某一个城市设置检查点,那么被设置的检查点受保护 ...

  7. codeforce 427 C. Checkposts(tarjan 强连通分量)

    题目链接:http://codeforces.com/contest/427/problem/C 题目大意是有n个junctions,这些junctions之间有m条道路,两两相连,现在在juncti ...

  8. [poj 2553]The Bottom of a Graph[Tarjan强连通分量]

    题意: 求出度为0的强连通分量. 思路: 缩点 具体有两种实现: 1.遍历所有边, 边的两端点不在同一强连通分量的话, 将出发点所在强连通分量出度+1. #include <cstdio> ...

  9. [poj 1904]King's Quest[Tarjan强连通分量]

    题意:(当时没看懂...) N个王子和N个女孩, 每个王子喜欢若干女孩. 给出每个王子喜欢的女孩编号, 再给出一种王子和女孩的完美匹配. 求每个王子分别可以和那些女孩结婚可以满足最终每个王子都能找到一 ...

随机推荐

  1. Vue前端挂载对象时一些思考

    最近,在Vue前端调试http请求,无论如何如何也是拦截不了某些http请求.场景是这样的:Java后端组装好Vue对象,然后送到前端,前端通过id来挂载该Vue对象,而该对象中有上传文件或者图片的控 ...

  2. Treats for the Cows POJ - 3186 dp 区间dp

    //dp[i][j]表示第i次从左边取,第j次从右边取的价值,所以我们可以得到状态方程 //dp[i][j]=max(dp[i-1][j]+(i+j)*a[i],dp[i][j-1]+(i+j)*a[ ...

  3. ubuntu set up 4 - 设置和软件

    1. Top Bar显示日期 https://askubuntu.com/questions/966576/customizing-tray-taskbar-date-display-in-ubunt ...

  4. Codeforce 515A - Drazil and Date

    Someday, Drazil wanted to go on date with Varda. Drazil and Varda live on Cartesian plane. Drazil's ...

  5. JS使用知识点理解

    var keyValue = $.request("keyValue"); $(function () { ////修改页面select下拉选框js $("#BloodB ...

  6. SQLserver中存储图片

    两种方式1.存放图片路径2.转换成2进制流(不过这样的话将很占用数据库空间)存路径的方式就很简单了,下面着重给出转换成2进制流的存入以及读取方法.存入:string FilePath="&q ...

  7. BZOJ3680 JSOI2004 平衡点 - 随机/近似算法

    迭代乱搞了下就过了…… #include <bits/stdc++.h> using namespace std; ],y[],w[]; double xm,ym,wt,k,lambda= ...

  8. Linux常用命令: zip、unzip 压缩和解压缩命令

    zip基本用法是: zip [参数] [打包后的文件名] [打包的目录路径] 常用参数: -a 将文件转成ASCII模式 -F 尝试修复损坏的压缩文件 -h 显示帮助界面 -m 将文件压缩之后,删除源 ...

  9. JFinalSwagger插件

    个人博客 地址:http://www.wenhaofan.com/article/20190304101839 jfinal使用swagger的极简插件 码云地址:https://gitee.com/ ...

  10. C语言链表的中间结点

    给定一个带有头结点 head 的非空单链表,返回链表的中间结点. 如果有两个中间结点,则返回第二个中间结点. 示例 1: 输入:[1,2,3,4,5]输出:此列表中的结点 3 (序列化形式:[3,4, ...