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

题目大意:

  给出一个\(n\)个结点\(m\)条边的有向图(无自环、无重边,2 ≤ n ≤ 500, 1 ≤ m ≤ min(n(n - 1), 100000) ),问能否通过删除其中的某一条边,使得该图无环。

知识点:  拓扑排序、DFS

解题思路一:

  由于结点数不多,所以可以枚举每个入度不为\(0\)的点,删去通向它的一条边(即使其入度减一),再跑拓扑排序判断有没有环。

AC代码一:

 #include <bits/stdc++.h>

 using namespace std;
const int maxn = , maxm = ;
vector<int> G[maxn];
int in[maxn],tin[maxn],stac[maxn]; bool topo(int n){
int top=,ending=;
for(int i=;i<=n;i++){
if(tin[i]==)
stac[ending++]=i;
}
while(top<ending){
int now=stac[top];
for(int i=;i<G[now].size();i++){
tin[G[now][i]]--;
if(tin[G[now][i]]==) stac[ending++]=G[now][i];
}
top++;
}
return ending>=n;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
in[v]++;
G[u].push_back(v);
}
for(int i=;i<=n;i++){
if(in[i]!=){
for(int j=;j<=n;j++) tin[j]=in[j];
tin[i]--;
if(topo(n)) return *puts("YES");
}
}
return *puts("NO");
}

解题思路二:

  先找出一个简单环,然后枚举删除该环上的每一条边,再跑拓扑排序判断还有没有环。

AC代码二:

#include <bits/stdc++.h>
using namespace std;
const int maxn = ; vector<int> G[maxn];
int mark[maxn],in[maxn],tin[maxn],last[maxn];
int cnt, loop[maxn];//cnt记录环上的结点数
bool dfs(int rt,int la){
last[rt]=la;
mark[rt]=; //访问过的结点,mark=1;
for(int i=;i<G[rt].size();i++){
if(mark[G[rt][i]]==){ //没有访问过的结点, mark=0
if(dfs(G[rt][i],rt)) return true;
}
if(mark[G[rt][i]]==){
int now=rt;
cnt=;
while(now!=G[rt][i]&&now!=-){
loop[cnt++]=now;
now=last[now];
}
loop[cnt++]=G[rt][i];
return true;
}
}
mark[rt]=-; //访问过并且会走到死路的结点,mark=-1
return false;
}
int stac[maxn];
bool topo(int n,int from,int to){//拓扑排序检查是否有环
int top=,ending=;
for(int i=;i<=n;i++){
if(tin[i]==)
stac[ending++]=i;
}
while(top<ending){
int now=stac[top];
for(int i=;i<G[now].size();i++){
if(now==from&&G[now][i]==to) continue;
tin[G[now][i]]--;
if(tin[G[now][i]]==) stac[ending++]=G[now][i];
}
top++;
}
return ending>=n;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
in[v]++; //记录入度
}
for(int i=;i<=n;i++){
if(mark[i]==){
if(dfs(i,-)) break;
}
}
if(!cnt) return *puts("YES");
for(int i=;i<cnt;i++){
for(int j=;j<=n;j++) tin[j]=in[j];
tin[loop[(i+)%cnt]]--;
if(topo(n,loop[i],loop[(i+)%cnt])) return *puts("YES");
}
return *puts("NO");
}

CF915D Almost Acyclic Graph的更多相关文章

  1. algorithm@ Shortest Path in Directed Acyclic Graph (O(|V|+|E|) time)

    Given a Weighted Directed Acyclic Graph and a source vertex in the graph, find the shortest paths fr ...

  2. 【CodeForces】915 D. Almost Acyclic Graph 拓扑排序找环

    [题目]D. Almost Acyclic Graph [题意]给定n个点的有向图(无重边),问能否删除一条边使得全图无环.n<=500,m<=10^5. [算法]拓扑排序 [题解]找到一 ...

  3. Almost Acyclic Graph CodeForces - 915D (思维+拓扑排序判环)

    Almost Acyclic Graph CodeForces - 915D time limit per test 1 second memory limit per test 256 megaby ...

  4. D. Almost Acyclic Graph 判断减一条边能不能得到DAG

    D. Almost Acyclic Graph time limit per test 1 second memory limit per test 256 megabytes input stand ...

  5. 题解 CF915D 【Almost Acyclic Graph】

    这道题我第一次的想法是直接判环的数量,然而事实证明实在是太naive了. 随便画个图都可以卡掉我的解法.(不知道在想什么) 这道题的正解是拓扑排序. 朴素的想法是对所有边都跑一次拓扑,但这样$O(m( ...

  6. CodeForces 915D Almost Acyclic Graph

    Description You are given a directed graph consisting of \(n\) vertices and \(m\) edges (each edge i ...

  7. 拓扑排序-有向无环图(DAG, Directed Acyclic Graph)

    条件: 1.每个顶点出现且只出现一次. 2.若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面. 有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说. 一 ...

  8. Almost Acyclic Graph CodeForces - 915D (思维,图论)

    大意: 给定无向图, 求是否能删除一条边后使图无环 直接枚举边判环复杂度过大, 实际上删除一条边可以看做将该边从一个顶点上拿开, 直接枚举顶点即可 复杂度$O(n(n+m))$ #include &l ...

  9. Almost Acyclic Graph Codeforces - 915D

    以前做过的题都不会了.... 此题做法:优化的暴力 有一个显然的暴力:枚举每一条边试着删掉 注意到题目要求使得图无环,那么找出图上任意一个环,都应当要在其某一处断开(当然没有环是YES) 因此找出图中 ...

随机推荐

  1. iterm2终端manpage高亮显示

    iterm2 据说是macOS平台上最好用的终端工具,今天下载来用了一下,发现确实很好.但是在使用man命令显示manpage的时候,颜色配置不是很让人满意,就像下面这样: 其实这样也是不错的,但是用 ...

  2. Node Mysql事务处理封装

    node回调函数的方式使得数据库事务貌似并没有像java.php那样编写简单,网上找了一些事务处理的封装并没有达到自己预期的那样简单编写,还是自己封装一个吧.封装的大体思路很简单:函数接受一个事务处理 ...

  3. DeepWalk论文精读:(3)实验

    模块三 1 实验设计 1.1 数据集 BLOGCATALOG[39]:博客作者网络.标签为作者感兴趣的主题. FLICKR[39]:照片分享网站的用户网络.标签为用户的兴趣群组,如"黑白照片 ...

  4. HTML--HTML入门篇(我想10分钟入门HTML,可以,交给我吧)

    我要正经的讲一节课,咳咳! HTML简介(废话) HTML称为超文本标记语言,是一种标识性的语言.它包括一系列标签.通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整 ...

  5. P2542 【[AHOI2005]航线规划】

    P2542 [[AHOI2005]航线规划] 一个无向图,m个操作 删去一条边 给定两个点,求有多少边使得如果这条边不存在,给定的两个点不连通 一般这种删边的题目,考虑逆序加边处理 在删完的图中,任意 ...

  6. andorid jar/库源码解析之EventBus

    目录:andorid jar/库源码解析 EventBus: 作用: 用于不同Activity,Service等之间传递消息(数据). 栗子: A页面:onCreate定义   EventBus.ge ...

  7. redis系列之4----redis高级应用(集群搭建、集群分区原理、集群操作)

    文章主目录 Redis集群简介 Redis集群搭建 Redis集群分区原理 集群操作 参考文档 本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 ...

  8. Java中的动态定义数组

    1.一维矩阵的动态定义(代码注释) 1.1方法一 package dongtai; import java.util.Scanner; import java.util.ArrayList; publ ...

  9. react中this.setState的理解

    this.setState作用? 在react中要修改this.state要使用this.setState,因为this.state只是一个对象,单纯的修改state并不会触发ui更新.所以我们需要用 ...

  10. [codeforces525D]BFS

    题目大意: 给定一个包含'.'和'*'的地图,每次操作可以把'*'->'.',用最少的操作使得新图满足条件:所有的连通块为矩形('.'为可达点) 解法: 用bfs来模拟操作的过程,对于一个2*2 ...