6-16 单词 uva10129

了解了欧拉回路和欧拉道路的性质 :

 

欧拉道路  最多只有两个奇点(不可能只有一个奇点)     并且当有两个奇点的时候  一个奇点入比出多一   一个奇点出比入多一

 

采用并查集查看是否连同   如果连通块大于等于2  显然不成立

 

然后判断 入数组 和出数组的个数  当处于个数不相同的时候说明有奇点   判断此时一个为入奇点 一个为出奇点!!

十分巧妙

根据查找连通性不同  有两种方式:

并查集

#include<bits/stdc++.h>
using namespace std;
int f[26];
int vis[26];
int in[26];
int out[26];


int find1(int x)
{
    return f[x]==x?x:f[x]=find1( f[x]  );
}

void uni(int a,int b)
{
    if(find1(a)!=find1(b))
    {
        f[a]=b;
    }
}



char m1[1000][1000];
char m2[1000][2];

int main()
{

    int cas;cin>>cas;
    while(cas--)
    {
      int n;cin>>n;
      memset(vis,0,sizeof(vis));
      memset(in,0,sizeof(in));
      memset(out,0,sizeof(out));
      for(int i=0;i<26;i++) f[i]=i;
      string s;getchar();
      while(n--)
      {
          getline(cin,s);
          in[s[0]-'a' ]++;  out[s[s.size()-1]-'a'   ]++;
          vis[ s[0]-'a'  ]=vis[ s[s.size()-1]-'a'  ]=1;

          uni( f[s[0]-'a'],f[s[s.size()-1]-'a' ]);
      }

        int cnt=0;
        for(int i=0;i<26;i++)
        {
            if(vis[i]&&f[i]==i)cnt++;
        }
        if(cnt>=2){printf("The door cannot be opened.\n");continue;}

        int ru=-1,chu=-1;

        int ok=1;
        for(int i=0;i<26;i++)
        {

            if(vis[i]&&in[i]!=out[i])
            {
                if(in[i]==out[i]+1&&ru==-1)ru=1;
                else if(in[i]==out[i]-1&&chu==-1)chu=1;
                else ok=0;
            }


        }

       if(ok)printf("Ordering is possible.\n");
       else printf("The door cannot be opened.\n");




    }









    return 0;
}
View Code

 

DFS 

#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
#define MAXN 100
using namespace std;
int vis[MAXN],G[MAXN][MAXN],N, T,f[MAXN],rank[MAXN], in[MAXN],out[MAXN];
 
void dfs(int u){
    vis[u] = true;
    for(int i=0; i<MAXN; ++i){
        if(G[u][i] && !vis[i])
            dfs(i);
    }
}
 
int main(){
 
    freopen("input.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        memset(G, 0, sizeof(G));
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));
 
        char str[1005];
 
        scanf("%d",&N);
        
        for(int i=0; i<N; ++i){
            scanf("%s", str);
            ++G[str[0]-'a'][str[strlen(str)-1]-'a'];
            ++out[str[0]-'a'];
            ++in[str[strlen(str)-1]-'a'];
        }
 
        bool flag=true;
 
        int num1=0, num2=0;
        for(int i=0; i<MAXN; ++i){
            if(!flag) break;
            if(in[i]!=out[i]){
                if(in[i]==out[i]+1) { ++num1; }
                else if(out[i]==in[i]+1) { ++num2; }
                else {flag=false; break; }
            }
        }
 
        if(num1 && num2 && num1+num2>2) flag=false;
 
        if(flag){
            memset(vis, 0, sizeof(vis));
            for(int i=0; i<MAXN; ++i) 
                if(out[i]) { dfs(i); break; }
 
            bool flag2=true;
            for(int i=0; i<MAXN; ++i){
                if(in[i] && !vis[i]) { flag2=false; break; }
                if(out[i] && !vis[i]) { flag2=false; break; }
            }
            if(flag2) printf("Ordering is possible.\n");
            else printf("The door cannot be opened.\n");
        }
        else{
            printf("The door cannot be opened.\n");
        }
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/bxd123/p/10310914.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值