zoukankan      html  css  js  c++  java
  • CF555E. Case of Computer Network

    题目大意

    题解

    缩点双前缀和判断,注意连通性与重边

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    #define ll long long
    //#define file
    using namespace std;
    
    int a[400001][2],ls[200001],num[200001],fa[200001][18],d[200001],f[200001][2],Num[200001],n,m,Q,i,j,k,l,x,y,z,len;
    void New(int x,int y) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;}
    bool bz[200001];
    namespace G{
    	int a[400002][2],ls[200001],dfn[200001],low[200001],d[200002],len=1,i,j,k,l,tot;
    	bool bz[200001];
    	void New(int x,int y) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;}
    	
    	void dfs(int Fa,int t)
    	{
    		int i;
    		dfn[t]=low[t]=++j;
    		bz[t]=1,d[++l]=t,d[l+1]=0;
    		
    		for (i=ls[t]; i; i=a[i][1])
    		if ((i/2)!=Fa)
    		{
    			if (!dfn[a[i][0]])
    			{
    				dfs(i/2,a[i][0]),low[t]=min(low[t],low[a[i][0]]);
    				if (dfn[t]<low[a[i][0]])
    				{
    					++tot;
    					while (d[l+1]!=a[i][0])
    					bz[d[l]]=0,num[d[l--]]=tot;
    				}
    			}
    			else
    			if (bz[a[i][0]])
    			low[t]=min(low[t],dfn[a[i][0]]);
    		}
    		
    		if (!Fa && l)
    		{
    			++tot;
    			while (l)
    			num[d[l--]]=tot;
    		}
    	}
    };
    
    void swap(int &x,int &y) {int z=x;x=y;y=z;}
    int lca(int x,int y)
    {
    	int i;
    	if (d[x]<d[y]) swap(x,y);
    	fd(i,17,0) if (d[fa[x][i]]>=d[y]) x=fa[x][i];
    	fd(i,17,0) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
    	if (x!=y) x=fa[x][0];
    	return x;
    }
    void dfs(int Fa,int t)
    {
    	int i;
    	bz[t]=1,Num[t]=k,d[t]=d[Fa]+1;
    	fa[t][0]=Fa;
    	fo(i,1,17) fa[t][i]=fa[fa[t][i-1]][i-1];
    	
    	for (i=ls[t]; i; i=a[i][1])
    	if (a[i][0]!=Fa && !bz[a[i][0]])
    	dfs(t,a[i][0]);
    }
    void Dfs(int Fa,int t)
    {
    	int i;
    	bz[t]=0;
    	for (i=ls[t]; i; i=a[i][1])
    	if (a[i][0]!=Fa && bz[a[i][0]])
    	{
    		Dfs(t,a[i][0]),f[t][0]+=f[a[i][0]][0],f[t][1]+=f[a[i][0]][1];
    		if (f[a[i][0]][0] && f[a[i][0]][1])
    		{
    			printf("No
    ");
    			exit(0);
    		}
    	}
    }
    
    int main()
    {
    	#ifdef file
    	freopen("CF555E.in","r",stdin);
    	#endif
    	
    	scanf("%d%d%d",&n,&m,&Q);
    	fo(i,1,m) scanf("%d%d",&x,&y),G::New(x,y),G::New(y,x);
    	
    	fo(l,1,n)
    	if (!G::dfn[l])
    	G::dfs(0,l);
    	fo(i,1,n)
    	{
    		for (j=G::ls[i]; j; j=G::a[j][1])
    		if (num[i]<num[G::a[j][0]])
    		New(num[i],num[G::a[j][0]]),New(num[G::a[j][0]],num[i]);
    	}
    	
    	k=0;
    	fo(l,1,n)
    	if (!d[l])
    	++k,dfs(0,l);
    	for (;Q;--Q)
    	{
    		scanf("%d%d",&x,&y),x=num[x],y=num[y];
    		if (Num[x]!=Num[y]) {printf("No
    ");return 0;}
    		if (x!=y)
    		l=lca(x,y),++f[x][0],--f[l][0],++f[y][1],--f[l][1];
    	}
    	Dfs(0,1);
    	printf("Yes
    ");
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    [DB] 数据库的连接
    JS leetcode 翻转字符串里的单词 题解分析
    JS leetcode 拥有最多糖果的孩子 题解分析,六一快乐。
    JS leetcode 搜索插入位置 题解分析
    JS leetcode 杨辉三角Ⅱ 题解分析
    JS leetcode 寻找数组的中心索引 题解分析
    JS leetcode 移除元素 题解分析
    JS leetcode 最大连续1的个数 题解分析
    JS leetcode 两数之和 II
    JS leetcode 反转字符串 题解分析
  • 原文地址:https://www.cnblogs.com/gmh77/p/13669675.html
Copyright © 2011-2022 走看看