是否存在欧拉路径问题 POJ - 1386 hihoCoder - 1181

本文探讨了如何通过构建图论模型解决特定问题,包括判断字符串能否头尾相连形成环状结构及寻找欧拉路径的方法。介绍了使用邻接表存储图数据结构,并通过深度优先搜索实现欧拉路径的查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

poj - 1386
//题意: 给出结果字符串, 问他们是否可以头尾相连起来.
//思路: 以每个单词的头和尾作为节点, 每个单词头尾之间连接一条有向边, 最后看是否可以找到一条有向欧拉路径即可. 注意两点:
1: 根据有向欧拉路的判定, 最后cnt最好是标记的入度和出度不等的顶点数, 因为如果有欧拉路, cnt一定等于0. 否则的话做法稍显麻烦.
2: 一定要判当前的图中是否联通. 不联通的话那直接就是NO了.

AC Code

const int maxn = 100+5;
int cas=1;
int out[maxn],in[maxn];
int fa[maxn];
int Find(int x)
{
    return fa[x] == x? x: fa[x] = Find(fa[x]);
}
void solve()
{
    Fill(in,0); Fill(out,0);
    for(int i=1;i<=26;i++) fa[i] = i;
    int n; scanf("%d",&n);
    while(n--){
        string s; cin >> s;
        int len = s.size();
        int t1 = s[0]-'a'+1; int t2 = s[len-1]-'a'+1;
        out[t1]++; in[t2]++;
        if(Find(t1) != Find(t2)) fa[Find(t2)] = Find(t1);
    }
    int tt = 0;
    int ans1=0,ans2=0;
    for(int i=1;i<=26;i++){
        if(!in[i] && !out[i]) continue;
        if(Find(i) == i) tt++;   //这里还要注意下是找Find(i),而不是fa[i],坑了好久.
        if(abs(in[i]-out[i]) == 1) ans2++;
        else if(in[i] != out[i]) ans1++;
    }
    if(ans1 == 0 && (ans2 == 0 || ans2 == 2) && tt == 1) puts("Ordering is possible.");
    else puts("The door cannot be opened.");
}

hihoCoder - 1181
题意和思路就不说了, 题面都有,说说几个注意点就是了.
1: 这个是根据点来建的图, 边上是没有东西的, 转化也不容易转化, 又因为要删边, 所以选择使用临接表来存图.
2: 注意两个点之间可能不只一条路.

AC Code

const int maxn = 1e3+5;
int cas=1;
int du[maxn],path[maxn];
int mapp[maxn][maxn];
int n,m,top=0;
void dfs(int u)
{
    for(int i=1;i<=n;i++){
        if(mapp[u][i]){
            mapp[u][i]--; mapp[i][u]--;
            dfs(i);
        }
    }
    path[top++] = u;
}
void solve()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v; scanf("%d%d",&u,&v);
        mapp[u][v]++; mapp[v][u]++;
        du[u]++; du[v]++;
    }
    int flag = 1;
    for(int i=1;i<=n;i++){
        if(du[i] & 1) {
            dfs(i); flag = 0;
            break;
        }
    }
    if(flag) dfs(1);
    for(int i=0;i<top;i++){
        printf("%d%c",path[i],i==top-1?'\n':' ');
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值