P3520 SMI-Garbage

题面:https://www.luogu.org/problemnew/show/P3520

本题直接用跑欧拉回路找环即可。

Code:
#include<bits/stdc++.h>
using namespace std;
int t,ansn,n,m,dis[2200000],f[2200000],vis[120000];
int sum,num=-1,du[120000],first[2200000],nex[2200000],to[2200000];
void add(int u,int v)
{
    nex[++num]=first[u];
    to[num]=v;
    first[u]=num;
}
void dfs(int u,int root)
{
    f[++sum]=u;
    du[u]-=2;
    for(int i=first[u];i!=-1;i=nex[i])
    {
        first[u]=i;
        if(dis[i]) continue;
        dis[i]=dis[i^1]=1;
        if(u!=root&&to[i]==root) 
        {
            ansn++;
            f[++sum]=to[i];
            return;
        }
        dfs(to[i],root);
        return;
    }
}
int main()
{
    memset(first,-1,sizeof(first));
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u,v,p,q;
        scanf("%d%d%d%d",&u,&v,&p,&q);
        if(p^q)
        {
            add(u,v);
            add(v,u);
            du[u]++;
            du[v]++;
        }
    }
    for(int i=1;i<=n;i++)
        if(du[i]&1)
        {
            printf("NIE\n");
            return 0;
        }
    for(int i=1;i<=n;i++)
    {
        if(!du[i]) continue;
        while(du[i])
            dfs(i,i);
    }
    printf("%d\n",ansn);
    int i=1;
    while(i<=sum)
    {
        int root=f[i],k=1;
        i++;
        while(f[i]!=root&&i<=sum)
            k++,i++;
        printf("%d ",k);
        for(int j=i-k;j<=i;j++)
            printf("%d ",f[j]);
        printf("\n");
        i++;
    }
    return 0;
}
posted @ 2019-07-15 14:03  prestige  阅读(121)  评论(0编辑  收藏  举报