您的位置:首页 > 其它

SGU 101 domino

2013-05-14 10:57 316 查看
坑点:vector建边时要注意当一条边是自己连自己时,要特殊判断一下,不然反向边会建错。 而这会导致前一个边的反向边建错,而不会影响后一个,这就是为什么出现改变一下搜边顺序就可以AC的情况。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<stack>
#include<fstream>
using namespace std;
struct EdgeType{
    int to,num,rev;
    bool mark1,mark2;
    EdgeType *next;
}EE[210],*Edge[10];
bool used[10],can[10];
int deg[10],cnt;
stack<int> s1;
stack<bool> s2;
void Init()
{
    memset(used,false,sizeof(used));
    memset(can,false,sizeof(can));
    memset(deg,0,sizeof(deg));
    cnt=0;
    while(!s1.empty())
        s1.pop();
    while(!s2.empty())
        s2.pop();
}
void AddEdge(int u,int v,int num)
{
    used[u]=true,used[v]=true;
    EE[cnt].to=v,EE[cnt].num=num,EE[cnt].rev=cnt+1,EE[cnt].mark1=true,EE[cnt].mark2=false;
    EE[cnt].next=Edge[u],Edge[u]=&EE[cnt];
    cnt++;
    EE[cnt].to=u,EE[cnt].num=num,EE[cnt].rev=cnt-1,EE[cnt].mark1=false,EE[cnt].mark2=false;
    EE[cnt].next=Edge[v],Edge[v]=&EE[cnt];
    cnt++;
    deg[u]++,deg[v]++;
}
void DFS(int u)
{
//    printf("DFS %d\n",u);
    can[u]=true;
    int v;
    EdgeType *t=Edge[u];
    while(t)
    {
        v=t->to;
        if(!can[v])
            DFS(v);
        t=t->next;
    }
}
void Eular(int u)
{
    EdgeType *t=Edge[u];
    while(t)
    {
        if(!t->mark2)
        {
//            printf("Eular %d %d %d\n",u,t->to,t->num);
            t->mark2=true;
            EE[t->rev].mark2=true;
            Eular(t->to);
            s1.push(t->num),s2.push(t->mark1);
        }
        t=t->next;
    }
}
bool Judge()   //ÅжÏÂú×ãÅ·À­Â·¾¶Ìõ¼þ
{
    int i;
    for(i=0;i<=6;++i)
    {
        if(used[i])
        {
            DFS(i);
            break;
        }
    }
    for(i=0;i<=6;++i)
    {
        if(used[i]&&!can[i])
            return false;
    }
//    printf("connected\n");
    int cnt=0;
    for(i=0;i<=6;++i)
    {
        if(deg[i]%2)
            cnt++;
    }
    if(cnt==0)
    {
//        printf("cnt==0\n");
        for(i=0;i<=6;++i)
        {
            if(used[i])
            {
                Eular(i);
                break;
            }
        }
        return true;
    }
    else if(cnt==2)
    {
//        printf("cnt==2\n");
        for(i=0;i<=6;++i)
        {
            if(used[i]&°[i]%2==1)
            {
                Eular(i);
                break;
            }
        }
        return true;
    }
    return false;
}
int main()
{
    int i,n,tl,tr;
    while(scanf("%d",&n)!=EOF)
    {
        Init();
        for(i=1;i<=n;++i)
        {
            scanf("%d %d",&tl,&tr);
            AddEdge(tl,tr,i);
        }
        if(Judge()==false)
        {
            printf("No solution\n");
        }
        else
        {
            while(!s1.empty())
            {
                printf("%d %c\n",s1.top(),s2.top()?'+':'-');
                s1.pop(),s2.pop();
            }
        }
    }
    return 0;
}




#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stack>
#include<vector>
#include<fstream>
using namespace std;
struct EdgeType{
    int to,num,rev;
    bool mark1,mark2;
    EdgeType(int t,int n,int r,bool m1,bool m2)
    {
        to=t,num=n,rev=r,mark1=m1,mark2=m2;
    }
};
vector<EdgeType> Edge[10];
int Deg[10];
bool Used[10],Hash[10];
stack<int> S1;
stack<bool> S2;
void Init()
{
    int i;
    for(i=0;i<10;++i)
        Edge[i].clear();
    memset(Deg,0,sizeof(Deg));
    memset(Used,0,sizeof(Used));
    memset(Hash,0,sizeof(Hash));
    while(!S1.empty())
        S1.pop();
    while(!S2.empty())
        S2.pop();
}
void DFS(int u)
{
//    printf("DFS %d\n",u);
    Hash[u]=true;
    int i,v;
    for(i=0;i<Edge[u].size();++i)
    {
        v=Edge[u][i].to;
        if(!Hash[v])
            DFS(v);
    }
}
void Eular(int u)
{
    int i;
    for(i=0;i<Edge[u].size();++i)  //wa test 3 原因是因为建边时出错
//    for(i=Edge[u].size()-1;i>=0;--i)
    {
        if(!Edge[u][i].mark1)
        {
//            printf("Eular %d %d %d\n",u,Edge[u][i].to,Edge[u][i].num);
            Edge[u][i].mark1=true,Edge[Edge[u][i].to][Edge[u][i].rev].mark1=true;
            Eular(Edge[u][i].to);
            S1.push(Edge[u][i].num),S2.push(Edge[u][i].mark2);
        }
    }
}
void AddEdge(int u,int v,int num)
{
    int r1,r2;
    if(u!=v)                                   //这里注意需要特殊判断一下,不然反向边会连错
        r1=Edge[v].size(),r2=Edge[u].size();
    else
        r1=Edge[v].size()+1,r2=Edge[u].size();
    Edge[u].push_back(EdgeType(v,num,r1,false,true));
    Edge[v].push_back(EdgeType(u,num,r2,false,false));
    Used[u]=true,Used[v]=true;
    Deg[u]++,Deg[v]++;
}
bool Work()
{
    int i;
     for(i=0;i<7;++i)
    {
        if(Used[i])
        {
            DFS(i);
            break;
        }
    }
    for(i=0;i<7;++i)
    {
        if(Used[i]&&!Hash[i])
            return false;
    }
    int cnt=0;
//    printf("connected\n");
    for(i=0;i<7;++i)
    {
        if(Deg[i]%2)
            cnt++;
    }
    if(cnt==0)
    {
//        printf("cnt==0\n");
        for(i=0;i<7;++i)
        {
            if(Used[i])
            {
                Eular(i);
                break;
            }
        }
        return true;
    }
    else if(cnt==2)
    {
//        printf("cnt==2\n");
        for(i=0;i<7;++i)
        {
            if(Used[i]&&Deg[i]%2==1)
            {
                Eular(i);
                break;
            }
        }
        return true;
    }
    return false;
}
int main()
{
    int n,i,u,v;
    while(scanf("%d",&n)!=EOF)
    {
        Init();
        for(i=1;i<=n;++i)
        {
            scanf("%d %d",&u,&v);
            AddEdge(u,v,i);
        }
        if(Work()==false)
            printf("No solution\n");
        else
        {
            while(!S1.empty())
            {
                printf("%d %c\n",S1.top(),S2.top()?'+':'-');
                S1.pop(),S2.pop();
            }
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: