• noip模拟63


    考试过程:这次考试四个题基本上都是计数题,我觉得不太可做,就按顺序开题。

    首先是T1,瓶颈就在于找环,但是我想了半天,没什么思路,只会\(o(n)\)找环,但是这样做复杂度是\(n\times m\)的,可以获得10pts的高分,再加上一个特殊性质,最终我获得了20pts的高分

    然后是T2,首先是考虑XIN队算法,但是这个暴搜和之前的不太一样,需要想一下。

    冲完XIN队后我看了看后面两个题,无思路,就又回来想T2,看到特殊性质,我就想拿这一档的分,但是我理解错了,它说的是区间没有相交,我当时以为区间嵌套和相交是没有关系的,结果考完试后强者cty告诉我嵌套是包含于相交的,我谔谔。那这部分算是白打了,以后一定要理解题意。

    T1 电机压制

    思路:建一棵DFS树,则特殊边就全部为返祖边。
    \(odd_u\)对结点\(u\)统计奇环,\(even_u\)统计偶环.设一条返祖边为 \(u -> v\)若它形成奇环,则\(odd[u]++\),\(odd[v]--\).
    \(x\)的子树所有结点的\(odd\)之和,即为\(x ->fa\)这条边被多少奇环包含(利用差分前缀和的思想)
    注意实现细节:
    1.当只有一个奇环的时候需要特判一下最后那一条边是不是重边,如果是那就没有贡献,否则的话\(ans++\)
    2.若自己的儿子对答案造成了贡献,但是自己和儿子的连边是重边,那么\(ans--\)
    代码如下:

    AC_code
    #include<bits/stdc++.h>
    #define re register int
    #define ii inline int
    #define iv inline void
    #define mid ((l+r)>>1)
    #define lc (rt<<1)
    #define rc (rt<<1|1)
    #define f() cout<<"fuck"<<endl
    #define head headddd
    #define next net
    using namespace std;
    const int N=2e5+10;
    unordered_map<int,bool> mp[N],no[N];
    int n,m,tot,num,com,ans,fw;
    int to[N<<1],head[N],next[N<<1],deep[N];
    int odd[N],even[N],ji[N];
    bool vis[N],flag;
    ii read()
    {
    	int x=0;char ch=getchar();bool f=1;
    	while(ch<'0' or ch>'9')
    	{
    		if(ch=='-') f=0;
    		ch=getchar();
    	}
    	while(ch>='0' and ch<='9')
    	{
    		x=(x<<1)+(x<<3)+(ch^48);
    		ch=getchar();
    	}
    	return f?x:(-x);
    }
    iv add(int x,int y)
    {
    	to[++tot]=y;
    	next[tot]=head[x];
    	head[x]=tot;
    }
    iv dfs(int st,int f)
    {
    	vis[st]=1;
    	deep[st]=deep[f]+1;
    	for(re i=head[st];i;i=next[i])
    	{	
    		int p=to[i];
    		if(p==f) continue;
    		if(vis[p])
    		{
    			if(deep[p]>deep[st]) continue;
    			if((deep[st]-deep[p]+1)&1) ++odd[st],--odd[p],++num;
    			else ++even[st],--even[p],++com;
    			continue;
    		}
    		dfs(p,st);
    	}
    }	
    iv dfs2(int st,int f)
    {
    	vis[st]=1;
    	for(re i=head[st];i;i=next[i])
    	{
    		int p=to[i];
    		if(vis[p]) continue;
    		dfs2(p,st);
    		if(odd[p]==num and even[p]==0 and no[st][p]) --ans;
    		odd[st]+=odd[p],even[st]+=even[p];
    	}
    	for(re i=head[st];i;i=next[i])
    	{
    		int p=to[i];
    		if(vis[p] and deep[p]<deep[st] and no[st][p] and odd[st]==num and even[st]==0) flag=1;
    	}
    }
    signed main()
    {
    	freopen("a.in","r",stdin),freopen("a.out","w",stdout);
    	n=read(),m=read();
    	int u,v;
    	for(re i=1;i<=m;i++)
    	{
    		u=read(),v=read();
    		if(mp[v].find(u)==mp[v].end()) add(u,v),add(v,u),mp[v][u]=mp[u][v]=1;	
    		else
    		{
    			if(no[v][u]) fw++;
    			else fw+=2;
    			no[v][u]=no[u][v]=1;
    		}
    	}
    	dfs(1,0);
    	for(re i=1;i<=n;i++) vis[i]=0;
    	dfs2(1,0);
    	if(num!=0 or com!=0)
    	{
    		for(re i=2;i<=n;i++) if(odd[i]==num and even[i]==0) ++ans;
    		if(num==1 and !flag) ans++;
    	}
    	else ans=m-fw;
    	printf("%d\n",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    ThinkPHP如果表名有下划线需要用Model应该怎么做?
    JS三级联动实例
    Sublime的使用!emmet常用快捷键梳理
    MUI极简的JS函数
    Atitit 自然语言处理原理与实现 attilax总结
    Atitit 自然语言处理原理与实现 attilax总结
    Atitit  自动化gui 与 发帖机 技术
    Atitit  自动化gui 与 发帖机 技术
    Atitit 衡量项目的规模
    Atitit 衡量项目的规模
  • 原文地址:https://www.cnblogs.com/WindZR/p/15345416.html
Copyright © 2020-2023  润新知