Codeforces915 D. Almost Acyclic Graph(思维,拓扑排序原理,拓扑排序判环)
Posted live4m
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces915 D. Almost Acyclic Graph(思维,拓扑排序原理,拓扑排序判环)相关的知识,希望对你有一定的参考价值。
题意:
解法:
题目是删除一条边之后,使得图变为DAG,问是否有解.
容易想到枚举删除的边,然后判断是否是DAG.
判断DAG可以用拓扑排序.
但是枚举边O(m),拓扑排序O(n+m),总复杂度O(m*(n+m)),没办法过.
删除一条边,在拓扑排序中的影响其实只是这条边出点的度数在跑之前减少了1,
那么其实我们枚举度数减少的点就行了.
枚举点的复杂度只有O(n),那么总复杂度就变为O(n*(n+m)),
由于n只有500,所以可以通过此题.
code:
#include<bits/stdc++.h>
// #define MULTI_CASE
#define SYNC_OFF
#define PI pair<int,int>
#define ll long long
#define int long long
using namespace std;
// const int mod=998244353;
const int mod=1e9+7;
const int maxm=2e6+5;
vector<int>g[maxm];
int deg[maxm];
int d[maxm];
int n,m;
bool check(int idx){
for(int i=1;i<=n;i++){
d[i]=deg[i];
}
d[idx]--;
queue<int>q;
for(int i=1;i<=n;i++){
if(!d[i]){
q.push(i);
}
}
while(q.size()){
int x=q.front();q.pop();
for(int v:g[x]){
if(d[v]){
d[v]--;
if(!d[v]){
q.push(v);
}
}
}
}
for(int i=1;i<=n;i++){
if(d[i]){
return 0;
}
}
return 1;
}
void solve(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;cin>>x>>y;
g[x].push_back(y);
deg[y]++;
}
int ok=0;
for(int i=1;i<=n;i++){
if(deg[i]&&check(i)){//有入度才可以删
ok=1;break;
}
}
if(ok)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
void Main(){
#ifdef MULTI_CASE
int T;cin>>T;while(T--)
#endif
solve();
}
void Init(){
#ifdef SYNC_OFF
ios::sync_with_stdio(0);cin.tie(0);
#endif
#ifndef ONLINE_JUDGE
freopen("../in.txt","r",stdin);
freopen("../out.txt","w",stdout);
#endif
}
signed main(){
Init();
Main();
return 0;
}
以上是关于Codeforces915 D. Almost Acyclic Graph(思维,拓扑排序原理,拓扑排序判环)的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 915D Almost Acyclic Graph
Almost Acyclic Graph CodeForces - 915D (思维+拓扑排序判环)
Codeforces 915D Almost Acyclic Graph
Almost Acyclic Graph Codeforces - 915D
codeforces 915D Almost Acyclic Graph 拓扑排序
Codeforces Round #481 (Div. 3) D. Almost Arithmetic Progression