[JSOI2015] represents a minimum

BZOJ

The meaning of problems: Given a \ (N \) points \ (M \) have edges in a directed acyclic graph, if so desired communication between any two points of the picture remains unchanged, deleted up to the number of sides ? \ (N <= 30000, M <= 100000.. \)

Analysis: For a side \ ((U, V) \) , it can be deleted, if and only if there is another path \ (u-> v \) path.

For the directed acyclic graph, we need to think of topological sorting, regarded as one of the ideas have seen a directed acyclic graph.

Each node topological sort \ (I \) recording an access time \ (NUM [I] = Tim \) , then the node for each edge node in accordance with the access time of arrival in ascending order and then follow the visit descending time to traverse the entire FIG. open a \ (N * N \) a \ (the bitset \) recording for each node \ (I \) , if it is currently possible to reach node \ (J \) , if the \ (F [I] [J] =. 1 \) . traverse to a node \ (U \) , the scan and the node which is connected to the \ (V \) , if the \ (f [u] [num [v] ] \) is already equal to 1, and then this edge is deleted, else let \ (f [U] [NUM [v]] = 1 \) , while \ (f [u] | = f [v] \ ) , expressed reservations \ ((U, v) \) after this edge, can reach the point v, u by v can arrive (according to the topology sequence, has been updated over prior v u).

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=30005;
const int M=100005;
int n,m,tim,ans,deg[N],num[N],st[N];
vector<int>g[N];queue<int>q;bitset<N>f[N];
inline void topsort(){
    for(int i=1;i<=n;++i)if(!deg[i])q.push(i);
    while(q.size()){
        int u=q.front();q.pop();
        num[u]=++tim;st[tim]=u;
        for(int i=0;i<(int)g[u].size();++i){
            int v=g[u][i];--deg[v];
            if(!deg[v])q.push(v);
        }
    }
}
inline bool cmp(const int &x,const int &y){return num[x]<num[y];}
int main(){
    n=read();m=read();
    for(int i=1;i<=m;++i){
        int u=read(),v=read();
        g[u].push_back(v);++deg[v];
    }
    topsort();
    for(int i=1;i<=n;++i)
        if(g[i].size())sort(g[i].begin(),g[i].end(),cmp);
    for(int i=tim;i>=1;--i){
        int u=st[i];
        for(int j=0;j<(int)g[u].size();++j){
            int v=g[u][j];
            if(f[u][num[v]]==1)++ans;
            else f[u][num[v]]=1,f[u]|=f[v];
        }
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/PPXppx/p/11719428.html