• [CLYZ2017]day13


    组织

    image

    solution

    20分

    缩环,暴力判\(DAG\)中的点两两之间连通性.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define M 105
    #define N 100005
    using namespace std;
    typedef long long ll;
    struct graph{
    	int nxt,to;
    }e[N];
    int g[N],f[N],l[N],r[N],s[N],to[M],dfn[N],low[N],n,m,t,top,cnt;
    bool a[M][M],ins[N];
    queue<int> q;
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline void addedge(int x,int y){
    //	printf("%d %d\n",x,y);
    	e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;
    }
    inline void tarjan(int u){
    	dfn[u]=low[u]=++cnt;
    	s[++top]=u;ins[u]=true;
    	for(int i=g[u];i;i=e[i].nxt)
    		if(!dfn[e[i].to]){
    			tarjan(e[i].to);
    			low[u]=min(low[u],low[e[i].to]); 
    		}
    		else if(ins[e[i].to])
    			low[u]=min(low[u],low[e[i].to]); 
    	if(dfn[u]==low[u])
    		while(s[top+1]!=u){
    			f[s[top]]=u;
    			ins[s[top--]]=false; 
    		}
    }
    inline void bfs(){
    	int u;cnt=0;
    	for(int i=1;i<=n;++i)
    		if(!to[i]) q.push(i);
    	while(!q.empty()){
    		s[++cnt]=u=q.front();q.pop();
    		for(int i=g[u];i;i=e[i].nxt)
    			if(!(--to[e[i].to]))
    				q.push(e[i].to);
    	}
    	for(u=s[cnt--];cnt>=0;u=s[cnt--])
    		for(int i=g[u];i;i=e[i].nxt){
    			a[u][e[i].to]=true;
    			for(int j=1;j<=n;++j)
    				a[u][j]|=a[e[i].to][j];
    		}
    }
    inline void Aireen(){
    	scanf("%d",&n);
    	scanf("%d",&m);
    	for(int i=1;i<=m;++i){
    		scanf("%d%d",&l[i],&r[i]);
    		addedge(l[i],r[i]);
    	}
    	cnt=0;
    	for(int i=1;i<=n;++i)
    		if(!dfn[i]) tarjan(i);
    	if(n<=100){
    		cnt=0;
    		memset(g,0,sizeof(g));
    		for(int i=1;i<=m;++i)
    			if(f[l[i]]!=f[r[i]]){
    				addedge(f[l[i]],f[r[i]]);++to[r[i]];
    			}
    		bfs(); 
    		scanf("%d",&t);
    		for(int i=1,j,k;i<=t;++i){
    			scanf("%d%d",&j,&k);
    			if(f[j]==f[k]||a[f[j]][f[k]]){
    				puts("NO");return;
    			}
    		}
    		puts("YES"); 
    		printf("%d\n",m);
    		for(int i=1;i<=m;++i)
    			printf("%d %d\n",l[i],r[i]);
    		return;
    	}
    	scanf("%d",&t);
    	for(int i=1,j,k;i<=t;++i){
    		scanf("%d%d",&j,&k);
    		if(f[j]!=f[k]){
    			puts("NO");return;
    		}
    	}
    	puts("YES"); 
    	printf("%d\n",m);
    	for(int i=1;i<=m;++i)
    		printf("%d %d\n",l[i],r[i]);
    }
    int main(){
    	freopen("gplt.in","r",stdin);
    	freopen("gplt.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    100分

    缩环,分块,用\(bitset\)求出所有点到这一块的点的连通性,判是否可行.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<bitset>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define M 10000
    #define N 100005
    #define min(a,b) a<b?a:b
    using namespace std;
    typedef long long ll;
    struct graph{
    	int nxt,to;
    }e[N];
    int g[N],l[N],r[N],x[N],y[N],n,m,k,cnt;
    bitset<M+10> a[N];
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline void addedge(int x,int y){
    	e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;
    }
    int f[N],s[N],dfn[N],low[N],top;bool ins[N];
    inline void tarjan(int u){
    	dfn[u]=low[u]=++cnt;
    	s[++top]=u;ins[u]=true;
    	for(int i=g[u];i;i=e[i].nxt)
    		if(!dfn[e[i].to]){
    			tarjan(e[i].to);
    			low[u]=min(low[u],low[e[i].to]); 
    		}
    		else if(ins[e[i].to])
    			low[u]=min(low[u],low[e[i].to]); 
    	if(dfn[u]==low[u])
    		while(s[top+1]!=u){
    			f[s[top]]=u;
    			ins[s[top--]]=false; 
    		}
    }
    int to[N],q[N],h,t;
    inline void topo(){
    	int u;h=1;
    	for(int i=1;i<=n;++i)
    		if(!to[i]) q[++t]=i;
    	while(h<=t){
    		u=q[h++];
    		for(int i=g[u];i;i=e[i].nxt)
    			if(!(--to[e[i].to])) q[++t]=e[i].to;
    	}
    }
    inline void func(int b,int end){
    	for(int i=1;i<=n;++i)
    		a[i].reset();
    	for(int i=b;i<=end;++i)
    		a[i][i-b+1]=1;
    	for(int i=t;i;--i)
    		for(int j=g[q[i]];j;j=e[j].nxt)
    			a[q[i]]|=a[e[j].to]; 
    }
    inline void Aireen(){
    	n=read();m=read();
    	for(int i=1;i<=m;++i){
    		l[i]=read();r[i]=read();
    		addedge(l[i],r[i]); 
    	}
    	cnt=0;
    	for(int i=1;i<=n;++i)
    		if(!dfn[i]) tarjan(i);
    	memset(g,0,sizeof(g));cnt=0;
    	for(int i=1;i<=m;++i)
    		if(f[l[i]]!=f[r[i]]){
    			addedge(f[l[i]],f[r[i]]);++to[r[i]];
    		}
    	topo();
    	k=read();
    	for(int i=1;i<=k;++i){
    		x[i]=read();y[i]=read();
    		if(f[x[i]]==f[y[i]]){
    			puts("NO");return;
    		}
    	}
    	for(int i=0;i*M+1<=n;++i){
    		func(i*M+1,(i+1)*M); 
    		for(int j=1;j<=k;++j)
    			if(y[j]>i*M&&y[j]<=(i+1)*M&&a[x[j]][y[j]-i*M]){
    				puts("NO");return;
    			}
    	}
    	puts("YES"); 
    	printf("%d\n",m);
    	for(int i=1;i<=m;++i)
    		printf("%d %d\n",l[i],r[i]);
    }
    int main(){
    	freopen("gplt.in","r",stdin);
    	freopen("gplt.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    JVM堆内存设置和测试
    转:面试题:“你能不能谈谈,java GC是在什么时候,对什么东西,做了什么事情?”
    JVM--标记-清除算法Mark-Sweep
    JVM 垃圾回收器工作原理及使用实例介绍
    BSGS算法(大小步算法)
    Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)
    Codeforces Round #605 (Div. 3)
    POJ 2516Minimum Cost(最小费用流+特判)
    POJ 3155Hard Life(最大密度子图)
    洛谷P2463 [SDOI2008]Sandy的卡片(后缀数组SA + 差分 + 二分答案)
  • 原文地址:https://www.cnblogs.com/AireenYe/p/CLYZ2017day13.html
Copyright © 2020-2023  润新知