Educational Codeforces Round 36 D. Almost Acyclic Graph 拓扑排序判环

D. Almost Acyclic Graph

题意:一个有向图,问最多删去一条边后,是否能不存在环。

tags:找出一个环,然后环上每条边假设删去一次,每次判一下是否还有环。 O(n*m)

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 505, M = 100005;

int n, m, vis2[M], head[N], tot;
int cycle[N], cnt;
bool vis[N];
struct Edge {
    int to, next;
} e[M];
void Addedge(int u, int v) {
    e[tot]=(Edge){ v, head[u] };  head[u]=tot++;
}
void Init() {
    mes(head, -1);
}
int ti;
bool dfs(int u)
{
    vis[u] = true;
    cycle[++cnt] = u;
    for(int i=head[u], to; ~i, to=e[i].to; i=e[i].next)
    {
        if(to==ti)  return true;
        if(!vis[to] && dfs(to)) return true;
    }
    --cnt;
    return false;
}
map< pair<int , int > , int >  mp;
queue< int > vec;
int in[N], in2[N];
bool Toposort()
{
    int u;
    while(!vec.empty())
    {
        u = vec.front(); vec.pop();
        for(int i=head[u], to, id;  ~i, to=e[i].to, id=mp[MP(u,to)];  i=e[i].next)
            if(vis2[id]==0)
            {
                vis2[id]=1;
                --in[to];
                if(in[to]==0) vec.push(to);
            }
    }
    rep(i,1,m) if(vis2[i]==0) return false;
    return true;
}
int main()
{
    scanf("%d%d", &n, &m);
    Init();
    int u, v;
    rep(i,1,m)
    {
        scanf("%d%d", &u, &v);
        Addedge(u, v);
        mp[MP(u, v)] = i;
        ++in2[v];
    }
    rep(i,1,n)
    {
        mes(vis, false);
        ti = i;
        if(dfs(i)) break;
        cnt = 0;
    }
    if(cnt==0) return 0*printf("YES
");
    cycle[++cnt] = ti;
    rep(i,1,cnt-1)
    {
        mes(vis2, 0);
        vis2[ mp[MP(cycle[i],cycle[i+1])] ] = -1;
        --in2[cycle[i+1]];
        rep(i,1,n) {
            if(in2[i]==0) vec.push(i);
            in[i] = in2[i];
        }
        if(Toposort())  return 0*printf("YES
");
        ++in2[cycle[i+1]];
    }
    puts("NO");

    return 0;
}
原文地址:https://www.cnblogs.com/sbfhy/p/8298903.html