P3520 [POI2011]SMI-Garbage

這是一道歐拉回路的板子題,惟一的不一樣在於要輸出是怎麼在那幾個環上轉出的答案,這樣就不能用鄰接矩陣存圖(其實本題的數據也直接否認了鄰接矩陣存圖的方法)node

不斷的在尋找一個簡單環,並在它上轉一次,至關於消掉一個環,並把全部路徑記錄在一個 stack 之中,在 stack 中必定會造成 這樣一種路徑 a.....a b......b c.......c由於最後必定會轉回起點,因此能夠倒序輸出一個被同一終點起點包圍的點c++

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
    int to,nxt;
}e[2000010];int tot;
int first[2000010];
int ind[2000010];
stack<int>sta;
queue<int>q;
int ans;
inline void add_edge(int a,int b){
    e[++tot].to=b,e[tot].nxt=first[a],first[a]=tot;
    e[++tot].to=a,e[tot].nxt=first[b],first[b]=tot;
}
inline int kd(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
    return x*f;
}
void dfsl(int x,int root){
    ind[x]-=2;//由於正反兩邊都不能走了因此入度會減二 
    for(int i=first[x];i;i=e[i].nxt){
        int to=e[i].to;
        if(e[i].to==0)continue;
        else{
            e[i].to=e[((i-1)^1)+1].to=0; //正反兩邊都不能再走了,就破壞掉 
            if(to==root){
                sta.push(to),sta.push(x);
                return;
            }
            dfsl(to,root);
            sta.push(x);
            return;
        }
    }
}
int main(){
    n=kd(),m=kd();
    for(int i=1;i<=m;i++){
        int a=kd(),b=kd(),c=kd(),d=kd();
        if(c==d)continue;//只有在不一樣時纔有走這條邊的必要 
        else{
            add_edge(a,b);
            ind[a]++,ind[b]++;//添加邊和增長入度 
        }
    }
    for(int i=1;i<=n;i++){
        if(ind[i]&1){//若是有奇數入度的邊必定是不會有歐拉回路的 
            cout<<"NIE"<<endl;
            return 0;
        }
    }
    for(int i=1;i<=n;i++){
        if(ind[i]){
            while(ind[i]){
                dfsl(i,i);
                ans++;
            }
        }
    }
    printf("%d\n",ans);
    int root;
    while(sta.empty()==false){
        int now;
        now=sta.top();
        sta.pop();
        q.push(now);
        if(q.size()==1){//若是這是一個開始 
            root=q.front();
        }
        else if(now==root){//若是陷入輪迴,這是一個結束 
            cout<<q.size()-1<<" "<<now<<" ";q.pop();
            while(q.empty()==false)cout<<q.front()<<" ",q.pop();//循環輸出在隊列裏保存好的路徑 
            puts("");
        }
    }
    return 0;
}
相關文章
相關標籤/搜索