您的位置:首页 > 其它

zoj 1919(AC) && poj 2337(WA) (并差集 + 欧拉回路或欧拉通路)

2013-01-10 16:53 489 查看
唉,zoj过了,poj挂了,不知道错在哪了,无解!

题意:很多单词,如果单词1的最后一个字每和单词2的第一个字母相同,那么这两个单词就可以连在一起,问所有的单词能不能连在一起,并按字典序输出。

{

有向图存在欧拉通路或回路的条件最多只有来两个节点的入度不等于初度,并且一个的in+1==out,另一个out+1==in;

}

把首位字母看成点,单词看成边,就是找欧拉回路或欧拉通路。如果是欧拉回路,那么找字典序最小的那个做起点,如果是欧拉通路,就是入度+1=初度的为起点。

#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
vector<int>e[1001];
int p[30],in[30],out[30],n,t,r,c;
int q[1111],vis[1111];
char s[1111][30];
int cmp(const void *s1,const void *s2)//qsort给字符串排序中的cmp;
{
    return strcmp((char *)s1,(char *)s2)>0;
}
void init()
{
    memset(vis,0,sizeof(vis));
    int i;
    for(i=1;i<=26;i++)
    {
        in[i]=out[i]=0;
        p[i]=i;
    }
    for(i=0;i<=1000;i++)
    e[i].clear();
}
int find(int i)
{
  if(p[i]!=i) return find(p[i]);
  return p[i];
}
void mege(int a,int b)
{
    a=find(a);
    b=find(b);
    if(a!=b)
    p[b]=a;
}
void Print(int i)//打印结果
{
    if(i!=-1)
    {
        Print(q[i]);
        if(c<n-1)
        printf("%s.",s[i]);
        else
        printf("%s",s[i]);
        c++;
    }
    else
    return;
}
void dfs(int i,int w)//dfs,当w==n时dfs结束。
{
    if(w==n)
    {
        r=1;
        Print(i);
        return;
    }
    else
    {
        if(r==0)
        {
            int j,l;
            for(j=0;j<e[i].size();j++)//vector存的是能与i相连的单词
            {
                l=e[i][j];
                if(!vis[l]&&i!=l)
                {
                    vis[l]=1;
                    q[l]=i;
                    dfs(l,w+1);
                    vis[l]=0;
                }
            }
        }
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        int i,j,start=0;
        r=c=0;
        init();
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            int L=strlen(s[i]);
            int a=s[i][0]-'a'+1;
            int b=s[i][L-1]-'a'+1;
            in[b]++;
            out[a]++;
            vis[a]=vis[b]=1;
            mege(a,b);
        }
        int tag=0,x=0,y=0,other=0,flag;//如果联通,那么tag应该==1;
        for(i=1;i<=26;i++)
        {
            if(vis[i])
            {
                if(find(i)==i)
                tag++;
                if(out[i]!=in[i])
                {
                    if(in[i]+1==out[i])
                    x++;
                    else if(in[i]-1==out[i])
                    y++;
                    else
                    other++;
                }
            }
        }
        if(tag==1&&other==0&&((x==0&&y==0)||(x==1&&y==1)))
        flag=1;
        else
        flag=0;
        if(!flag)
        {
            printf("***\n");
        }
        else
        {

            qsort(s,n,sizeof(s[0]),cmp);

            if(x==0&&y==0)//找起点
            {
                for(i=1;i<=26;i++)
                if(vis[i])
                {
                   start=i;break;
                }
            }
            else
            {
                for(i=1;i<=26;i++)
                {
                    if(vis[i]&&in[i]+1==out[i])
                    {
                        start=i;break;
                    }
                 }
            }
            for(i=0;i<n;i++)
            {
                int l=strlen(s[i]);
                for(j=0;j<n;j++)//找出i能与哪些相连
                {
                    if(i!=j&&s[i][l-1]==s[j][0])
                    e[i].push_back(j);
                }
            }
            for(i=0;i<n;i++)
            {
                if(s[i][0]-'a'+1==start)
                {
                    memset(vis,0,sizeof(vis));
                    q[i]=-1;
                    vis[i]=1;
                    dfs(i,1);
                }
                if(r) break;
            }

            printf("\n");
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: