• 【LOJ#2162】【POI2011】Garbage(欧拉回路)


    【LOJ#2162】【POI2011】Garbage(欧拉回路)

    题面

    LOJ

    题解

    首先有一个比较显然的结论,对于不需要修改颜色的边可以直接删掉,对于需要修改的边保留。说白点就是每条边要被访问的次数可以直接模二。证明的话就是如果一条边被经过了两次,证明其连通了两侧的两个块,那么把这两次删掉,可以把两侧各拆分成一个欧拉回路,不会影响答案。
    于是剩下的边直接对于每一个连通块算欧拉回路。
    然后对于强制定向之后的图直接(dfs)找到所有简单环就可以了。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    #define MAX 100100
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int n,m;
    int f[MAX];
    int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
    struct Line{int v,next;}e[MAX*20];
    int h[MAX],cnt=2,dg[MAX],cur[MAX];
    void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;dg[v]++;}
    bool vis[MAX*10];int dir[MAX*10];
    vector<int> Ans[MAX];int tot;
    void dfs(int u)
    {
    	for(int &i=cur[u];i;i=e[i].next)
    	{
    		if(vis[i>>1])continue;int j=i;
    		vis[i>>1]=true;dfs(e[i].v);
    		dir[j>>1]=j&1;
    	}
    }
    int St[MAX],top;bool inq[MAX];
    void DFS(int u)
    {
    	St[++top]=u;inq[u]=true;
    	for(int &i=h[u];i;i=e[i].next)
    	{
    		if(!inq[u])return;
    		int v=e[i].v;if((i&1)!=dir[i>>1])continue;
    		if(inq[v])
    		{
    			int p;++tot;Ans[tot].push_back(v);
    			do{p=St[top--];Ans[tot].push_back(p);inq[p]=false;}while(p!=v);
    			St[++top]=v;inq[v]=true;
    		}
    		else DFS(v);
    	}
    }
    int main()
    {
    	n=read();m=read();
    	for(int i=1;i<=n;++i)f[i]=i;
    	for(int i=1;i<=m;++i)
    	{
    		int u=read(),v=read(),s=read(),t=read();
    		if(s^t)Add(u,v),Add(v,u),f[getf(u)]=getf(v);
    	}
    	for(int i=1;i<=n;++i)if(dg[i]&1){puts("NIE");return 0;}
    	for(int i=1;i<=n;++i)cur[i]=h[i];
    	for(int i=1;i<=n;++i)if(getf(i)==i)dfs(i);
    	for(int i=1;i<=n;++i)DFS(i);
    	printf("%d
    ",tot);
    	for(int i=1;i<=tot;++i)
    	{
    		printf("%d ",(int)Ans[i].size()-1);
    		for(int u:Ans[i])printf("%d ",u);puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    如何用纯 CSS 创作一个蝴蝶标本展示框
    如何用纯 CSS 创作一个菱形 loader 动画
    如何用纯 CSS 创作背景色块变换的按钮特效
    如何用纯 CSS 绘制一个充满动感的 Vue logo
    css实现盒尺寸重置、均匀分布的子元素、截断文本
    Wireshark分析RabbitMQ
    MVC5 一套Action的登录控制流程
    MySQL timespan设置 sql_mode设置
    MVC webapi,Action的分别拦截器
    CentOS7.2 安装RabbitMQ3.6.10
  • 原文地址:https://www.cnblogs.com/cjyyb/p/11153950.html
Copyright © 2020-2023  润新知