zoukankan      html  css  js  c++  java
  • [JSOI2015]最小表示

    之前连bitset都不会写......为了写这道题去学习了一下bitset的用法

    首先要得到一个很显然的结论,就是如果(x)(y)之间的边可以被删去,那么(x)一定可以通过别的路径走到(y),然后在这里我们就需要用bitset来维护点与点之间的连通性

    因为这是一个有向无环图,所以我们直接拓扑排序,然后从出度为零的点逆序入队,将每一个结点的子节点按照到出度为零的点的距离由大到小排序,可以保证最优,然后判一下(bit[x][son])是不是1,如果是1就说明这条边是可以删掉的

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,x,y,r[30003],ru[30003],p,hd,st[30003],ans;
    queue<int>q;
    vector<int>l[30003];
    bitset<30003>bit[30003];
    int cmp(int nx,int ny)
    {
    	return r[nx]>r[ny];
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		l[x].push_back(y),ru[y]++;
    	}
    	for(int i=1;i<=n;i++)
    		if(ru[i]==0)
    			q.push(i);
    	while(!q.empty())
    	{
    		p=q.front(),q.pop(),hd++,st[hd]=p;
    		for(int j=0;j<l[p].size();j++)
    		{
    			ru[l[p][j]]--;
    			if(ru[l[p][j]]==0)
    				q.push(l[p][j]);
    		}		
    	}
    	for(int i=n;i>=1;i--)
    	{
    		x=st[i],bit[x][x]=1;
    		sort(l[x].begin(),l[x].end(),cmp);
    		for(int j=0;j<l[x].size();j++)
    		{
    			r[x]=max(r[l[x][j]]+1,r[x]);
    			if(bit[x][l[x][j]]==1)
    				ans++;
    			else
    				bit[x]|=bit[l[x][j]];
    		}
    	}
    	cout<<ans;
    	return 0;
    }
    
    
  • 相关阅读:
    bzoj3110
    idea 设置系列 各种乱码
    vim 系列
    idea 神键
    简单工厂,工厂方法,抽象工厂
    log4 按包进行日志输出
    maven依赖本地宝
    kafka 理论学习
    kafka windows环境搭建 测试
    linux 查找文件的命令
  • 原文地址:https://www.cnblogs.com/dzice/p/12266044.html
Copyright © 2011-2022 走看看