CF915D Almost Acyclic Graph (思维+拓扑)

如果想要判定是否是DAG,用拓扑排序是一个好选择,但是本题可以删一条边

如果真的傻傻的去枚举删边就难顶了

我们要想到,对于删边,其实就是入度-1,而我们知道,删完能拓扑,说明成功了,因此只要枚举点,对入度操作再跑拓扑,就能AC

这个转化还是很有意思的,我们来思考正确性,首先对于一个环,肯定因为到了某个情况所有的入度都不为0,所以加不进队列。而对于环上一点,本来跑完拓扑之后就剩下环上的边,这次入度-1,相当于

忽略了环上的边,就成功了破解了,如果这个点上存在两个环,那还是没用,因为减完入度还有

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
int in[N],in1[N];
vector<int> g[N];
int n;
bool topo(){
    queue<int> q;
    int i;
    int sum=0;
    for(i=1;i<=n;i++){
        if(!in[i])
            q.push(i);
    }
    while(q.size()){
        int t=q.front();
        q.pop();
        sum++;
        for(i=0;i<g[t].size();i++){
            int j=g[t][i];
            in[j]--;
            if(!in[j])
                q.push(j);
        }
    }
    if(sum==n)
        return true;
    return false;
}
int main(){
    int i;
    int m;
    cin>>n>>m;
    for(i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        g[u].push_back(v);
        in[v]++;
        in1[v]++;
    }
    if(topo()){
        cout<<"YES"<<endl;
        return 0;
    }
    else{
        for(i=1;i<=n;i++){
            memcpy(in,in1,sizeof in);
            if(in[i]>=1){
                in[i]--;
                if(topo()){
                    cout<<"YES"<<endl;
                    return 0;
                }
            }
        }
    }
    cout<<"NO"<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/ctyakwf/p/12633734.html

时间: 2024-07-31 07:33:22

CF915D Almost Acyclic Graph (思维+拓扑)的相关文章

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

Almost Acyclic Graph CodeForces - 915D time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output You are given a directed graph consisting of n vertices and m edges (each edge is directed, so it can

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

[题目]D. Almost Acyclic Graph [题意]给定n个点的有向图(无重边),问能否删除一条边使得全图无环.n<=500,m<=10^5. [算法]拓扑排序 [题解]找到一个简单环,则欲删除的边一定经过该环.尝试环上的每一条边(至多n条边)后再次拓扑排序判断全图是否有环. 拓扑排序后定位到简单环:剩余图是环+环内DAG,DFS过程中将走入死路的点标-1,访问过标1,找到访问过的点就是简单环.换起始点直到找到环为止. 复杂度O(nm). #include<cstdio>

Codeforces 915D Almost Acyclic Graph

题意翻译 给定一个n个顶点,m条边的有向图.你允许从其中去掉最多一条边. 你能够去掉最多一条边就让这个图无环吗?我们称一个有向图无环,当且仅当它不包含一个环(起点和终点相同的路径). 输入格式: 第一行两个正整数n,mn,m 2\le n\le 500,1\le m\le min(n(n-1),100000)2≤n≤500,1≤m≤min(n(n?1),100000) ,代表图的顶点数和边数. 接下来mm 行,每行两个数u,vu,v ,表示有一条从uu 到vv 的有向边(1\le u,v\le

Almost Acyclic Graph Codeforces - 915D

以前做过的题都不会了.... 此题做法:优化的暴力 有一个显然的暴力:枚举每一条边试着删掉 注意到题目要求使得图无环,那么找出图上任意一个环,都应当要在其某一处断开(当然没有环是YES) 因此找出图中任意一个简单环(点不重复),枚举断开其上每一条边即可(共最多n条边) 复杂度O(n*(n+m)) 注意:不能用拓扑排序找出在任意环上的点再找任意环,因为拓扑排序后入度不为0的不一定是环上的点(比如可能是某个点,没有出边,仅有一条入边,是某个环上的点引出的)(曾经错了) 1 #include<cstd

HDU5957 Query on a graph(拓扑找环,BFS序,线段树更新,分类讨论)

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5957 题意:D(u,v)是节点u和节点v之间的距离,S(u,v)是一系列满足D(u,x)<=k的点的集合,操作1:将S(u,k)内节点权值增加或者减小,操作2:查询S(u,k)内节点的权值和 题解:因为题目说了查询和更新的距离小于等于k,k最大为2,所以很显然要分情况讨论k为0.1.2的情况 因为是多次更新,我们显然是需要用线段树来维护节点权值的 运用线段树和bfs序的知识我们知道 对一个棵树求BFS

Andrew and Taxi CodeForces - 1100E (思维,拓扑)

大意: 给定有向图, 每条边有一个权值, 假设你有$x$个控制器, 那么可以将所有权值不超过$x$的边翻转, 求最少的控制器数, 使得翻转后图无环 先二分转为判定问题. 每次check删除能动的边, 若剩余图有环显然不成立, 否则将剩余的图拓排一下, 再把能动的边按拓排的方向即可保证无环. #include <iostream> #include <algorithm> #include <math.h> #include <cstdio> #include

算法系列笔记6(有关图的算法一—搜索,拓扑排序和强连通分支)

简单概念:对于图G(V,E),通常有两种存储的数据结构,一种是邻接矩阵,此时所需要的存储空间为O(V^2):第二种是邻接表,所需要的存储空间为O(V+E).邻接表表示法存在很强的适应性,但是也有潜在的不足,当要快速的确定图中边(u,v)是否存在,只能在顶点u的邻接表中搜索v,没有更快的方法,此时就可以使用邻接矩阵,但要以占用更多的存储空间作为代价:此外当图不是加权的,采用邻接矩阵存储还有一个优势:在存储邻接矩阵的每个元素时,可以只用一个二进位,而不必用一个字的空间. 图的搜索算法 搜索一个图示有

数据结构--图(下)--拓扑排序

拓扑排序 思维导图也是图的一种 拓扑序:如果图中从V到W有一条有向路径,则V一定排在W之前.满足此条件的顶点排序成为一个拓扑序.  V->W 获得一个拓扑序的过程就是拓扑排序 AOV如果有合理的拓扑序,则必定是有向无环图(Directed Acyclic Graph,简称DAG). 第一排没有预修课程的课.然后抹掉顶点和边, 每一次输出哪个顶点呢,没有前驱顶点,就输出(入度为0的顶点). 最后的拓扑序就产生了 DAG有向无环图. 拓扑排序的应用 AOE(Activity On Edge)网络  

图的邻接表表示与无环图的拓扑排序

一.  图的最常用的表示方法是邻接矩阵和邻接表. 1,邻接矩阵 邻接矩阵其实就是一个二维数组,对于每条边<u,v>,我们就令A[u][v] = 1,如果图为有权图,我们也可以令A[u][v]等于该权,这么表示的优点是非常简单,但是它的空间需求很大,如果图是稠密的,邻接矩阵是合适的表示方法,如果图是稀疏的,那这种方法就太浪费空间了,下面给出图的邻接矩阵表示例子. 2 邻接表 邻接表是图的常用储存结构之一.邻接表由表头结点和表结点两部分组成,其中图中每个顶点均对应一个存储在数组中的表头结点.如下图