[POI2011]SMI-Garbage 题解

题面

想必各位大佬一定想到了把现在和目标值不一致的边加入到一个新建的图上;

问题就变为了在新的图上寻找有多少个欧拉回路,并输出这些路径;

我们可以用栈来记录情况,然后对于会回答稍微处理处理就好了;

#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
struct littlestar{
    int to;
    int nxt;
}star[2500010];
int head[2500010],cnt=1;
void add(int u,int v)
{
    star[++cnt].to=v;
    star[cnt].nxt=head[u];
    head[u]=cnt;
} 
int n,m;
int du[2500010];
int st[2500010],top;
int vis[2500010];
int ans;
void dfs(int u,int goal)
{
    st[++top]=u;
    du[u]--;
    du[u]--;
    for(int i=head[u];i;i=star[i].nxt){
        int v=star[i].to;
        head[u]=i;
        if(vis[i]) continue;
        vis[i]=vis[i^1]=1;
        if(u!=goal&&v==goal){
            ++ans;
            st[++top]=v;
            return;
        }
        dfs(v,goal);
        return ;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    inc(i,1,m){
        int u,v,w,goal;
        scanf("%d%d%d%d",&u,&v,&w,&goal);
        if(w==goal) continue;
        add(u,v);
        add(v,u);
        du[u]++;
        du[v]++;
    }
    inc(i,1,n){
        if(du[i]&1){
            cout<<"NIE"<<endl;
            return 0;
        }
    }
    inc(i,1,n){
        while(du[i]){
            dfs(i,i);
        }
    }
    cout<<ans<<endl;
    inc(i,1,top){
        int goal=st[i];
        ++i;
        int num=0;
        while(st[i]!=goal&&i<=top) ++i,++num;
        cout<<num+1<<" ";
        inc(j,i-num,i){
            printf("%d ",st[j]);
        }
        printf("%d",st[i-num]);
        cout<<endl;
    }
}

 

posted @ 2019-09-25 16:02  神之右大臣  阅读(120)  评论(0编辑  收藏  举报