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;
    }
    
  • 相关阅读:
    codeforces1068——D.Array Without Local Maximums(计数DP+前缀和优化)
    codeforces1253——D. Harmonious Graph(并查集)
    LDUOJ——I. 买汽水(折半搜索+双指针)
    洛谷P3360 ——偷天换日(dfs读入+树形DP+01背包)
    洛谷P1270 ——“访问”美术馆(dfs读入+树形DP)
    LDUOJ——最小生成树(欧拉函数+思维)
    [LeetCode] 1551. Minimum Operations to Make Array Equal
    [LeetCode] 1553. Minimum Number of Days to Eat N Oranges
    [LeetCode] 161. One Edit Distance
    [LeetCode] 1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/gmh77/p/13669675.html
Copyright © 2011-2022 走看看