zoukankan      html  css  js  c++  java
  • Luogu CF555E 【Case of Computer Network】

    其实如果这是一颗树的话很好搞,把(s)(lca(s,t)) 向上连,(lca(s,t))(t)向下连即可(然而事情并不是这样子的...)。
    我们考虑什么样的情况是一定可行的呢?每两个点之间都有两条以上的路径,那就可以一边向前,一边向后,绝对可以。也就是求双联通分量以内是一定可以的,所以考虑缩点。惊奇的发现得到了一片森林(两点之间最多一条边,否则就被缩点了),那不就好搞了嘛!特判在不同树上的情况,直接在缩点的时候暴力搞定就行。在同一棵树上可以树剖/树上差分维护。最后一遍dfs判定标记是否重复就行了
    那么现在问题就是怎没求双联通分量了...我并不会诶....(现场学习

    #include <cstdio>
    
    #define R register
    const int MAXN=2e5+10;
    const int MAXM=MAXN<<1;
    
    inline int read()
    {
    	#define C getchar()
    	char a=C;int x=0,f=1;
    	for(;a>'9'||a<'0';a=C) if(a=='-') f=-1;
    	for(;a>='0'&&a<='9';a=C) x=x*10+a-'0';
    	return x*f;
    	#undef C
    }
    
    inline int min(int x,int y) { return x<y?x:y;}
    
    int n,m,q;
    struct edge
    {
    	int fr,to,next;
    }e1[MAXM];
    
    struct Edge
    {
    	int to,next;
    }e2[MAXM];
    int head1[MAXN],cnt1=1;
    int head2[MAXN],cnt2=1;
    
    inline void add1(int x,int y)
    {
    	cnt1++;
    	e1[cnt1].fr=x;
    	e1[cnt1].to=y;
    	e1[cnt1].next=head1[x];
    	head1[x]=cnt1;
    }
    
    inline void add2(int x,int y)
    {
    	cnt2++;
    	e2[cnt2].to=y;
    	e2[cnt2].next=head2[x];
    	head2[x]=cnt2;
    }
    
    int dfn[MAXN],low[MAXN];
    int col[MAXN],num;
    int st[MAXN],tp;
    int vis[MAXN];
    int tot;
    int be[MAXN];
    
    inline void tarjan(int x,int fr)
    {
    	dfn[x]=low[x]=++num;
    	col[x]=col[0];
    	st[++tp]=x,vis[x]=1;
    	for(R int i=head1[x];i;i=e1[i].next)
    	{
    		if((i^1)==fr) continue;
    		int y=e1[i].to;
    		if(!dfn[y])
    		{
    			tarjan(y,i);
    			low[x]=min(low[x],low[y]);
    		}
    		else
    			if(vis[y]) low[x]=min(low[x],dfn[y]);
    	}
    	if(dfn[x]==low[x])
    	{
    		int y=0;tot++;
    		while(y!=x)
    		{
    			y=st[tp];tp--;
    			be[y]=tot;vis[y]=0;
    		}
    	}
    }
    
    int dep[MAXN],fa[MAXN],top[MAXN],siz[MAXN],son[MAXN];
    
    inline void dfs1(int x,int fx)
    {
    	dep[x]=dep[fx]+1;
    	fa[x]=fx;
    	siz[x]=1;
    	for(R int i=head2[x];i;i=e2[i].next)
    	{
    		int y=e2[i].to;
    		if(y==fx) continue;
    		dfs1(y,x);
    		siz[x]+=siz[y];
    		if(siz[y]>siz[son[x]]) son[x]=y;
    	}
    }
    
    inline void dfs2(int x,int topx)
    {
    	top[x]=topx;
    	if(son[x]) dfs2(son[x],topx);
    	for(R int i=head2[x];i;i=e2[i].next)
    	{
    		int y=e2[i].to;
    		if(y==fa[x]||y==son[x]) continue;
    		dfs2(y,y);
    	}
    }
    
    inline int lca(int x,int y)
    {
    	while(top[x]!=top[y])
    	{
    		if(dep[top[x]]>dep[top[y]])
    			x=fa[top[x]];
    		else
    			y=fa[top[y]];
    	}
    	return dep[x]<dep[y]?x:y;
    }
    
    int up[MAXN],down[MAXN];
    int tag[MAXN];
    
    inline void dfs3(int x)
    {
    	tag[x]=1;
    	for(R int i=head2[x];i;i=e2[i].next)
    	{
    		int y=e2[i].to;
    		if(y==fa[x]) continue;
    		dfs3(y);
    		up[x]+=up[y];
    		down[x]+=down[y];
    	}
    }
    
    int main()
    {
    	n=read();m=read();q=read();
    	for(R int i=1;i<=m;i++)
    	{
    		int x=read();int y=read();
    		add1(x,y);add1(y,x);
    	}
    	for(R int i=1;i<=n;i++)
    		if(!dfn[i])
    		{
    			col[0]++;
    			tarjan(i,0);
    		}
    	for(R int i=2;i<=cnt1;i+=2)
    	{
    		int x=e1[i].fr;
    		int y=e1[i].to;
    		if(be[x]==be[y]) continue;
    		add2(be[x],be[y]);
    		add2(be[y],be[x]);
    	}
    	for(R int i=1;i<=n;i++)
    		if(!dep[i])
    		{
    			dfs1(i,0);
    			dfs2(i,i);
    		}
    	for(R int i=1;i<=q;i++)
    	{
    		int x=read(),y=read();
    		if(col[x]!=col[y])
    		{
    			printf("No
    ");return 0;
    		}
    		x=be[x],y=be[y];
    		int LCA=lca(x,y);
    		up[x]++;up[LCA]--;
    		down[y]++;down[LCA]--;
    	}
    	for(R int i=1;i<=n;i++)
    		if(!tag[i]) dfs3(i);
    	for(R int i=1;i<=n;i++)
    		if(up[i]&&down[i])
    		{
    			printf("No
    ");
    			return 0;
    		}
    	printf("Yes
    ");
    	return 0;
    }
    
  • 相关阅读:
    洛谷—— P3353 在你窗外闪耀的星星
    洛谷—— P1238 走迷宫
    洛谷—— P1262 间谍网络
    9.8——模拟赛
    洛谷—— P1189 SEARCH
    算法
    May 22nd 2017 Week 21st Monday
    May 21st 2017 Week 21st Sunday
    May 20th 2017 Week 20th Saturday
    May 19th 2017 Week 20th Friday
  • 原文地址:https://www.cnblogs.com/clover4/p/12819924.html
Copyright © 2011-2022 走看看