zoukankan      html  css  js  c++  java
  • 拓扑排序,bitset~[JSOI2015]最小表示

    拓扑排序,bitset~[JSOI2015]最小表示

    传送门

    题意:在有向无环图中删尽可能多的边,使图连通性不变,输出最大数量。

    题解:写这题主要就是学一下bitset的用法,首先如果一个x到y的边可以删的话,说明从x到y有别的路可以走,从此还可以想到解此题的一个关键,如y可以到z,然后x连着y与z,我先让x和y连起来,则一次完成了x与y连通与z连通的任务,那么这个时候x到z就是条费边了,可加入答案,所以我们要将点的边进行排序,规则就是拓扑排序靠后的点排在后面,之后就是怎么记录y连着z,还有判断x到z是费边时怎么记录x已经与z连接起来了,这里我们用bitset去记录,这里就说几个关键的操作,bitset[x] [y]=1说明x已连接上y,bitset[x]|=bitset[y] 的意思是将y连接到的其他点也加入x。

    总结一下,先用拓扑排序列出搜点的顺序,再从无出点的点(逆序)开始,往前加边,同时对边排序。

    #include<iostream>
    #include<algorithm>
    #include<map>
    #include<bitset>
    #include<vector>
    #include<queue>
    using namespace std;
    #define pb push_back
    int n,m,v,u,ru[30007],dis[30007];
    vector<int>ho[30007];
    vector<int>edg;
    queue<int>sa;
    bitset<30007>se[30007];
    bool cmp(int a,int b){
    	return dis[a]<dis[b];
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&u,&v);
    		ho[u].pb(v);
    		ru[v]++;
    	}
    	for(int i=1;i<=n;i++){
    		if(ru[i]==0)sa.push(i);
    	}
    	int cnt=0;
    	while(!sa.empty()){
    		int lin=sa.front();
    		sa.pop();
    		dis[lin]=++cnt;
    		edg.pb(lin);
    		for(int i=0;i<ho[lin].size();i++){
    			ru[ho[lin][i]]--;
    			if(ru[ho[lin][i]]==0){
    				sa.push(ho[lin][i]);
    			}
    		}
    	}
    	for(int i=1;i<=n;i++){
    		sort(ho[i].begin(),ho[i].end(),cmp);
    	}
    	int len=edg.size()-1,lin,lin2,ans=0;
    	for(int i=len;i>=0;i--){
    		lin=edg[i];
    		se[lin][lin]=1;
    		for(int j=0;j<ho[lin].size();j++){
    			lin2=ho[lin][j];
    			if(se[lin][lin2]==1){
    				ans++;
    			}
    			else{
    				se[lin]|=se[lin2];
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
    
  • 相关阅读:
    yum提示Another app is currently holding the yum lock
    函数参数返回值作用域笔记
    递归内置函数笔记
    装饰器笔记
    函数笔记扩展
    集合笔记
    线程和进程
    函数笔记
    线程与进程的区别
    Ubuntu操作及各种命令笔记.txt
  • 原文地址:https://www.cnblogs.com/whitelily/p/13282149.html
Copyright © 2011-2022 走看看